1. diel - Tipy pre začiatočníkov v PHP
Vítam vás pri prvom článku série Tipy pre začiatočníkov v PHP. Ukážem vám niekoľko príkladov, kde je kódu zbytočne navyše a ktoré by sa mohli zapísať lepšie, jednoduchšie a v niektorých prípadoch by sa aj (hoci len minimálne) zlepšil výkon.
Ukážem vám zlé príklady a ak bude treba, tak sa pokúsim aj o riešenie, za ktoré by ste sa nemuseli hanbiť. Možno si niektorí z vás aj zaspomínajú na svoje vlastné začiatky pri programovaní a niektorým to môže pomôcť zbaviť sa zbytočného kódu. Ďakujem za prečítanie a nech sa články páči!
Začneme úplne jednoduchými príkladmi, ktoré sa v praxi nikde nevyskytujú. No, možno by ste sa divili ...
Nevhodné názvy premenných
A) Nič nehovoriace názov
Väčšinou je jednoduchšie napísať nejaký náhodný názov premennej, aby sa vymýšľaním názvov nezabil čas. Ide napríklad o takéto prípady:
1: $aaa = 10; 2: $x1 = array("a", "b"); 3: $x2 = array("c", "d"); 4: $x163 = "nějaký řetězec";
Prečo vymýšľať nejaké názvy, keď to rovnako raz niekde použijem a nebudem to viac riešiť? Problém nastáva vo chvíli, keď budete robiť väčšie script, takže si potom budete hovoriť:
6336: if ($x163 !== fooBar()) { 6337: // co že je to $x163 ?! 6338: ... 6339: }
Navyše chudáci kolegovia, ak niečo také uvidí v spoločnom projekte.
B) Miešanie jazykov
Ide o prípad, keď v názve použijete napríklad slovenčinu a angličtinu.
$numberOfLidi $pocetCars
Nejedná sa iba o konkrétnu premennú, ale v celom projekte by sa mal používať jeden jazyk, a to vrátane názvov funkcií a pod. V opačnom prípade vzniknú takéto kusy kódu:
if (count($inputData) > $naseSuperKonfigurace["dataStorage"]["maximalnyPocetZaznamov"]) { ... }
Zvyčajne je dobré písať celý program v angličtine. Jednak sú anglicky i kľúčové slová PHP, takže ak by ste chceli program zverejniť treba ako open-source, ostatné vývojári mu lepšie porozumie.
C) Zle zvolený názov
Ďalšie zlá situácia môže nastať v prípade, že použijete zlý názov. Pre ukážku to preženiem:
$karluvVek = array(-4, 10, "abc");
Je síce pekné, že ste zvolili určitý názov a dokonca aj v jednom
jazyku, ale pod názvom karlův věk
asi nebudete očakávať pole
s tromi rôznymi hodnotami (a ešte k tomu raz zápornú a tretí
reťazcom).
Výnimku tvoria napríklad premenné $ ia $ j, ktoré sa používajú pri iterácii (napr. Prechádzanie poľa).
Použitie mnohých podmienok ElseIf
Tento prípad je niekedy vidieť napríklad pri tvorbe dynamických stránok, kedy je názov prenášaný cez parameter v URL.
$page = $_GET["page"]; if ($page === "home") { include "home.php;" } elseif ($page === "about") { include "about.php"; } elseif ($page === "contact") { include "contact.php"; } elseif ($page === "sitemap") { include "sitemap.php"; } /* atd ... */ else { include "404.php"; }
Okrem toho, že to je dosť neprehľadné (predstavte si napríklad 100 rôznych stránok), tak zabijete hromadu riadkov a ešte keby ste náhodou chceli zmeniť názov premennej $ page, budete pekne prepisovať všetky podmienky.
Riešiť sa to dá veľmi jednoducho, keď si vytvoríte whitelist, čiže zoznam povolených hodnôt:
$page = $_GET["page"]; $allowedPages = array("home", "about", "contact", "sitemap"); if (isset($allowedPages[$page])) { $file = "{$page}.php"; include $file; } else { include "404.php"; }
Pole sa dá navyše jednoducho rozšíriť. Napríklad ak budete chcieť mať iný názov súboru, môžete si urobiť asociatívne pole:
$page = $_GET["page"]; $pages = array( "home" => "home.php", "about" => "aboutMe.php", ... ); if (isset($pages[$page])) { include $pages[$page]; } else { include "404.php"; }
code
Pole môžeme rozšíriť o ďalšie prvky, ktoré sa využijú na každej stránke.
<?php $page = $_GET["page"]; // budeme předpokládat, že parametr page v URL vždy existuje $pages = array( "home" => array( "file" => "home.php", "title" => "Domů", "needLogin" => FALSE ), "admin" => array( "file" => "admin/index.php", "title" => "Administrace", "needLogin" => TRUE ), "404" => array( "file" => "404.php", "title" => "Chyba 404, stránka nenalezena" ), "onlyForLoggedUsers" => array( "file" => "onlyForLoggedUsers.php", "title" => "Pouze pro přihlášené" ) ); if (isset($pages[$page])) { $pageData = $pages[$page]; if (isset($pageData["needLogin"]) && $pageData["needLogin"]) { // pokud stránka vyžaduje přihlášení, automaticky se provede kontrola if (!isset($_SESSION["userId"])) { $pageData = $pages["onlyForLoggedUsers"]; } } } else { $pageData = $pages["404"]; } ?> <html> <head> <meta charset="UTF-8" /> <title><?php $pageData["title"]; ?></title> </head> <body> <?php include $pageData["file"]; ?> </body> </html>
code
Tento príklad môže fungovať pre malé a veľmi jednoduché weby. Ak budete chcieť pridávať rôzne spracovanie formulárov, je lepšie ten kód zostaviť trochu inak (pretože by spracovanie formulára malo prebehnúť ešte pred akýmkoľvek výpisom HTML).
Prepisovanie hodnôt poľa
Ak budete potrebovať z nejakého dôvodu zmeniť hodnoty v nejakom poli, môžete to vyriešiť takýmto spôsobom:
$numbers = array(1, 2, 3, 4, 5); $count = count($numbers); for ($i = 0; $i < $count; $i++) { $numbers[$i] = $numbers[$i] * 2; }
code
Riadok s násobením možné pomocou referencie (odkaz na premennú) zjednodušiť:
foreach ($numbers as &$number) { $number = $number * 2; }
code
Všimnite si znaku & (ampersand) pred premennú $ number. Pomocou neho sa neskopíruje obsah daného prvku, ale uloží sa odkaz na miesto v pamäti. Znamená to, že ak upravíme hodnotu premennej $ number, tak sa zmení hodnota i daného prvku v poli.
Príliš veľké vetvenia
Veľké ponáranie podmienok možno vidieť napríklad u spracovanie formulárov. Jednoduchý príklad, ktorý by mohol znázorniť registráciu užívateľa:
if ($_POST) { if (!empty($_POST["name"])) { if (empty($_POST["pass"])) { if (empty($_POST["repass"])) { if (!empty($_POST["email"])) { if ($_POST["pass"] === $_POST["repass"]) { if (strlen($_POST["name"]) > 5) { // dokončení registrace } else { echo "Jméno obsahuje málo znaků"; } } else { echo "Hesla se neshodují"; } } else { echo "Nebyl zadán e-mail" } } else { echo "Nebylo zadáno kontrolní heslo"; } } else { echo "Nebylo zadáno heslo"; } } else { echo "Nebylo zadáno jméno"; } } // a to jsem tam nepřidal kontrolu mailu, znaků ve jméně a hromadu dalších potenciálních podmínek
code
Zbaviť sa tohto neprehľadného kódu je veľmi jednoduché. Tento spôsob nám dokonca umožní uložiť viac chýb, takže nie je nutné užívateľa zakaždým otravovať s jednou hláškou do doby, než sa rozhodne stránku zatvoriť.
$errors = array(); if ($_POST) { if (empty($_POST["name"])) { $errors[] = "Nebylo vyplněno jméno"; } if (empty($_POST["pass"])) { $errors[] = "Nebylo vyplněno heslo"; } if (empty($_POST["repass"])) { $errors[] = "Nebylo vyplněno kontrolní heslo"; } if (empty($_POST["email"])) { $errors[] = "Nebyl vyplněno e-mail"; } if (empty($errors)) { // pokud zatím nejsou žádné chyby, můžeme pokračovat dále if (strlen($_POST["name"]) <= 5) { $errors[] = "Jméno obsahuje příliš málo znaků"; } if ($_POST["pass"] !== $_POST["repass"]) { $errors[] = "Zadaná hesla se neshodují"; } if (empty($errors)) { // dokončení registrace } } }
code
Vypísať jednotlivé chyby potom môžete jednoducho pomocou cyklu.
if (!empty($errors)) { echo "<ul>"; foreach ($errors as $error) { echo "<li>{$error}</li>"; } echo "</ul>"; }
code
Riešenie samozrejme tiež obsahuje určité ponáranie, ale kód sa zrazu zdá oveľa prehľadnejšie. V podstate ide o sériu určitých podmienok, kde sa na konci zisťuje stav (sú chyby / nie sú chyby). Je to preto, aby sa pri nevyplnenie mená nezobrazila ako hláška "nevyplnené meno", tak i zároveň "meno obsahuje málo znakov".
Počítanie prvkov v poli počas cyklu
Často je v kóde vidieť, že sa používa funkcia count alebo sizeof (obe robia to isté), keď sa prechádza nejaké pole.
for ($i = 0; $i < count($fields); $i++) { // nějaký kód }
code
Pri prechádzaní cyklom sa zakaždým testuje podmienka. Znamená to, že sa zakaždým zavolá funkcie count (), aby prvky v poli spočítala. Chyba to nie je, len sa to zakaždým zbytočne počíta znova. Možno by to bolo poznať na výkone, keby to pole obsahovalo potrebné milión hodnôt. Riešením je spočítať prvky pred cyklom a do podmienky dosadzovať len premennú.
$fieldsCount = count($fields); for ($i = 0; $i < $fieldsCount; $i++) { // nějaký kód }
code
To je z prvého článku všetko. Ďakujem za prečítanie a ak bude záujem, rád sa toho pokúsim spísať viac (napríklad zbytočnosti pri práci s dátami z databázy atp.).