7. díl - Dokončení knihovny ArrayUtils v PHP

PHP Knihovny Dokončení knihovny ArrayUtils v PHP American English version English version

V minulém dílu našeho seriálu tutoriálů o tvorbě knihoven pro PHP jsme rozepsali knihovnu ArrayUtils pro práci s poli v PHP. Dnes knihovnu doplníme o další užitečné metody a tím ji dokončíme.

Přidání a odstranění prefixu klíčů

O prefixech jsme se již krátce zmínili. Představme si vložení adresy z formuláře do databáze. Názvy formulářových polí budou samozřejmě opět korespondovat s názvy sloupců v tabulce.

HTML část

...
Ulice: <input type="text" name="ulice" /><br />
Č. popisné: <input type="text" name="cislo_popisne" /><br />
Č. orientační: <input type="text" name="cislo_orientacni" /><br />
Město: <input type="text" name="mesto" /><br />
PSČ: <input type="text" name="psc" /><br />
...

PHP část

$kliceAdresa = array('ulice', 'cislo_popisne', 'cislo_orientacni', 'mesto', 'psc');
$adresa = ArrayUtils::filterKeys($_POST, $kliceAdresa);
Db::insert('adresa', $adresa);

Občas data ale dorazí z nějakého složitějšího formuláře, ve kterém máme např. 2 adresy - fakturační a dodací. Aby se nám kontrolky nepletly, předsadíme dodací adresu prefixem "dodaci_". Formulář by vypadal např. takto:

HTML část

...
<h2>Fakturační adresa</h2>
Ulice: <input type="text" name="ulice" /><br />
Č. popisné: <input type="text" name="cislo_popisne" /><br />
Č. orientační: <input type="text" name="cislo_orientacni" /><br />
Město: <input type="text" name="mesto" /><br />
PSČ: <input type="text" name="psc" /><br />
...

<h2>Dodací adresa</h2>
Ulice: <input type="text" name="dodaci_ulice" /><br />
Č. popisné: <input type="text" name="dodaci_cislo_popisne" /><br />
Č. orientační: <input type="text" name="dodaci_cislo_orientacni" /><br />
Město: <input type="text" name="dodaci_mesto" /><br />
PSČ: <input type="text" name="dodaci_psc" /><br />
...

PHP část

V PHP budeme chtít z $_POST vytáhnout část bez prefixů a část s prefixy, u té poté prefixy odstranit a uložit obě adresy do tabulky "adresa". Kód bude vypadat takto:

$kliceAdresa = array('ulice', 'cislo_popisne', 'cislo_orientacni', 'mesto', 'psc');
$fakturacniAdresa = ArrayUtils::filterKeys($_POST, $kliceAdresa);
// Získání jen polí s prefixem
$dodaciAdresa = ArrayUtils::filterKeysPrefix('dodaci_', $_POST);
// Odstranění prefixu
$dodaciAdresa = ArrayUtils::removePrefix('dodaci_', $dodaciAdresa);
// Filtrování
$dodaciAdresa = ArrayUtils::filterKeys($dodaciAdresa, $kliceAdresa);
// Vložení adres do databáze
Db::insert('adresa', $fakturacniAdresa);
Db::insert('adresa', $dodaciAdresa);

Uveďme si kód metod addPrefix() a removePrefix(). Všimněte si, že jsou napsané tak, aby fungovaly i rekurzivně.

public static function addPrefix($prefix, array $input)
{
        $output = array();
        foreach ($input as $key => $value)
        {
                $key = $prefix . $key;
                if (is_array($value))
                        $value = self::addPrefix($prefix, $value);
                $output[$key] = $value;
        }
        return $output;
}

public static function removePrefix($prefix, array $input)
{
        $output = array();
        foreach ($input as $key => $value)
        {
                if (strpos($key, $prefix) === 0)
                        $key = substr($key, mb_strlen($prefix));
                if (is_array($value))
                        $value = self::removePrefix($prefix, $value);
                $output[$key] = $value;
        }
        return $output;
}

Změna velbloudí notace na podtržítkovou a naopak

V MySQL databázi je zvykem pojmenovávat tabulky podtržítkovou­_notací (snake_case). Jednak se vyhneme problémům s velkými/malými písmeny na linuxových serverech a také nám např. PHPMyAdmin seskupuje tabulky podle dvou podtržítek, např. uzivatel__adresa, uzivatel__ban­kovni_ucet a podobně. V PHP ovšem používáme spíše VelbloudíNotaci (CamelCase). Někdy je užitečné převést klíče pole z jedné notace na druhou. A právě to dělají 2 níže uvedené funkce. K samotnému převodu je použita knihovna StringUtils, kterou jsme dokončili minule.

public static function camelToSnake($inputArray)
{
        $outputArray = array();
        foreach ($inputArray as $key => $value)
        {
                $key = StringUtils::camelToSnake($key);
                if (is_array($value))
                        $value = self::camelToSnake($value);
                $outputArray[$key] = $value;
        }
        return $outputArray;
}

public static function snakeToCamel($inputArray)
{
        $outputArray = array();
        foreach ($inputArray as $key => $value)
        {
                $key = StringUtils::snakeToCamel($key);
                if (is_array($value))
                        $value = self::snakeToCamel($value);
                $outputArray[$key] = $value;
        }
        return $outputArray;
}

Převod do XML

Při spolupráci s externími systémy často pracujeme s formáty JSON nebo XML. Oba tyto formáty je výhodné generovat z pole, přičemž pro generování pole do JSON a z JSON PHP obsahuje skvělé funkce. Generování pole do XML bohužel chybí a proto si za účelem této i zpětné konverze přidáme metody. Uveďme si nejprve kód metody xmlEncode():

public static function xmlEncode(array $input, $root)
{
        $doc = new DOMDocument('1.0', 'UTF-8');
        $doc->formatOutput = true;

        $rootElement = $doc->createElement($root);
        $doc->appendChild($rootElement);
        self::xmlEncodeElement($input, $rootElement);

        return $doc->saveXML();
}

private static function xmlEncodeElement(array $input, DOMElement $parent)
{
        foreach ($input as $key => $value)
        {
                $element = $parent->ownerDocument->createElement($key);
                $parent->appendChild($element);
                if (is_array($value))
                        self::xmlEncodeElement($value, $element);
                else
                {
                        $text = $parent->ownerDocument->createTextNode($value);
                        $element->appendChild($text);
                }
        }
}

Metoda přijímá vstupní pole a název kořenového XML elementu. Následně vytvoří nový dokument a přidá do něj kořenový element. Dále spustí privátní metodu xmlEncodeElement(). Ta přijímá pole a element, do kterého má prvky z pole přivěsit. Druhou metodu jsme vytvořili kvůli usnadnění rekurze, budeme chtít, aby bylo možné zanořit pole do sebe. Pro každý klíč pole zde vytvoříme element a do toho buď vložíme rovnou text nebo zavoláme metodu rekurzivně znovu pro případ, že je vkládanou hodnotu opět pole.

Metodu můžeme vyzkoušet:

$uzivatele = array(
        'administrator' => array(
                'uzivatel_id' => 1,
                'jmeno' => 'Jan Novák',
                'email' => 'jan@novak.cz',
        ),
        'redaktor' => array(
                'uzivatel_id' => 2,
                'jmeno' => 'Jana Nováková',
                'email' => 'jana@novakova.cz',
        ),
);
echo ArrayUtils::xmlEncode($uzivatele, 'uzivatele');

A výsledné XML:

<?xml version="1.0" encoding="UTF-8"?>
<uzivatele>
  <administrator>
    <uzivatel_id>1</uzivatel_id>
    <jmeno>Jan Novák</jmeno>
    <email>jan@novak.cz</email>
  </administrator>
  <redaktor>
    <uzivatel_id>2</uzivatel_id>
    <jmeno>Jana Nováková</jmeno>
    <email>jana@novakova.cz</email>
  </redaktor>
</uzivatele>

Pozn.: Při tvorbě XML z pole jsme samozřejmě limitovaní tím, že každý klíč může být v poli jen jednou. Některá XML tedy polem nevytvoříme, ale jindy nám ušetří spoustu práce.

Pro úplnost dodejme i zpětnou konverzi. Tentokrát využijeme malého hacku a to že metoda json_encode() dokáže přijímat objekt typu SimpleXMLElement. Výsledný JSON poté převedeme na pole pomocí json_decode():

public static function xmlDecode($xml)
{
        $simpleXMLElement = simplexml_load_string($xml);
        $json = json_encode($simpleXMLElement);
        return json_decode($json, TRUE);
}

A máme hotovo :) Kompletní a zdokumentovanou třídu naleznete jako vždy ke stažení níže. Příště se podíváme na formulářový framework.


 

Stáhnout

Staženo 99x (6.27 kB)
Aplikace je včetně zdrojových kódů v jazyce php

 

  Aktivity (2)

Článek pro vás napsal David Čápka
Avatar
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.

Jak se ti líbí článek?
Celkem (4 hlasů) :
4.754.754.754.754.75


 


Miniatura
Všechny články v sekci
Knihovny pro PHP

 

 

Komentáře

Avatar
lukincok
Člen
Avatar
lukincok:

Ahoj, vďaka za ďalší skvelý seriál.
No našiel som chybu v kóde - v definíciách metód addPrefix() a removePrefix() voláš tieto metódy rekurzívne, ale majú vymenené parametre oproti tomu ako sú definované.

Napr.:

public static function addPrefix($prefix, array $input)

a vo vnútri voláš takto:

$value = self::addPrefix($value, $prefix);

čo by malo byť podľa mňa takto:

$value = self::addPrefix($prefix, $value);

Hmm, alebo nie? :)

Pridávam prvý komentár k tomuto článku, som šťastný.

 
Odpovědět 3.7.2015 11:57
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na lukincok
David Čápka:

Díky, máš pravdu, bylo to tam prohozené :)

Odpovědět 3.7.2015 13:51
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 2 zpráv z 2.