Lekce 7 - Dokončení knihovny ArrayUtils v PHP
V minulé lekci, Knihovna ArrayUtils pro práci s poli v PHP, jsme rozepsali knihovnu ArrayUtils
pro práci s poli v PHP.
Dnes do knihovny ArrayUtils
přidáme práci s prefixy, konverzi
notací a ukážeme si převod pole do XML a naopak.
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:
<!-- ... --> <label>Ulice:<br/> <input type="text" name="ulice"/> </label><br/> <label>Č. popisné:<br/> <input type="text" name="cislo_popisne"/> </label><br/> <label>Č. orientační:<br/> <input type="text" name="cislo_orientacni"/> </label><br/> <label> Město:<br/> <input type="text" name="mesto"/> </label><br/> <label>PSČ:<br/> <input type="text" name="psc"/> </label><br/> <!-- ... -->
Formulář zpracujeme zkráceně takto:
$kliceAdresa = array('ulice', 'cislo_popisne', 'cislo_orientacni', 'mesto', 'psc'); $adresa = ArrayUtils::filterKeys($_POST, $kliceAdresa); Db::insert('adresa', $adresa);
Databázový wrapper (třída Db
) je dostupná z
kurzu PHP
databáze.
Složitější formulář
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:
<!-- ... --> <h2>Fakturační adresa</h2> <label>Ulice:<br/> <input type="text" name="ulice"/> </label><br/> <label>Č. popisné:<br/> <input type="text" name="cislo_popisne"/> </label><br/> <label>Č. orientační:<br/> <input type="text" name="cislo_orientacni"/> </label><br/> <label> Město:<br/> <input type="text" name="mesto"/> </label><br/> <label>PSČ:<br/> <input type="text" name="psc"/> </label><br/> <!-- ... --> <h2>Dodací adresa</h2> <label>Ulice:<br/> <input type="text" name="dodaci_ulice"/> </label><br/> <label>Č. popisné:<br/> <input type="text" name="dodaci_cislo_popisne"/> </label><br/> <label>Č. orientační:<br/> <input type="text" name="dodaci_cislo_orientacni"/> </label><br/> <label>Město:<br/> <input type="text" name="dodaci_mesto"/> </label><br/> <label>PSČ:<br/> <input type="text" name="dodaci_psc"/> </label><br/> <input type="submit"> <!-- ... -->
PHP část
V PHP budeme chtít z pole $_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(string $prefix, array $input): array { $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(string $prefix, array $input): array { $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; }
Metoda addPrefix()
rekurzivně přidá prefixy klíčům v poli,
druhá metoda removePrefix()
dělá opak, tedy rekurzivně
odstraní prefixy klíčů v poli.
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ř. nástroj
PhpMyAdmin seskupuje tabulky podle dvou podtržítek, např.
uzivatel__adresa
, uzivatel__bankovni_ucet
a podobně.
V PHP ovšem používáme spíše velbloudíNotaci (CamelCase s velkým prvním
písmenem, jinak je správný název PascalCase). Někdy je užitečné
převést klíče pole z jedné notace na druhou. A právě to dělají dvě
níže uvedené metody. K samotnému převodu je použita knihovna
StringUtils
, kterou jsme dokončili minule:
public static function camelToSnake(array $inputArray): array { $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(array $inputArray): array { $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, string $root): string { $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): void { 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>
Pokud chceme, aby se nám v prohlížeči zobrazilo XML
správně, musíme nastavit před jakýkoliv výpisem hlavičku
header('Content-type: text/xml')
.
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 funkce json_encode()
dokáže přijímat objekt
typu SimpleXMLElement
. Výsledný JSON poté převedeme na pole
pomocí funkce json_decode()
:
public static function xmlDecode(string $xml): array { $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.
V příští lekci, Knihovna Image pro práci s obrázky v PHP, začneme pracovat na knihovně pro práci s obrázky.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 336x (3.38 kB)
Aplikace je včetně zdrojových kódů v jazyce PHP