1. díl - Standardy jazyka PHP - Úvod a PSR-1

PHP Standardy Standardy jazyka PHP - Úvod a PSR-1

Vítejte u prvního dílu seriálu tutoriálů, ve kterém se budeme zaměřovat na správný zápis PHP kódu. Standardy jsou v programování velmi podceňované a málo kdo si je vědom toho, že špatně napsaná webová aplikace je nekompatibilní s okolním světem a nese si břemeno problematického nebo dokonce nemožného využívání knihoven třetích stran.

Proč jsou standardy důležité

PHP je jako jazyk velmi šikovné a rozšířené. Problém v něm ovšem nastává při tvorbě větších aplikací jako jsou komplexní informační systémy, CRM, rozšířenější CMS systémy o další moduly, e-shopy a podobně. Takové aplikace:

  • Jsou napsané objektově (velká aplikace je bez logického členění funkčnosti do objektů nepřehledná)
  • Obsahují velké množství tříd
  • Vyžadují přemýšlení nad architekturou (nestačí bezmyšlenkovitě přidávat další kód)
  • Využívají knihovny třetích stran

Tyto velké aplikace se často nepíší na zelené louce (od nuly), jelikož by to bylo velmi nákladné. Skládají se jako stavebnice z různých knihoven, frameworků, modulů a pluginů.

Uveďme si reálný příklad. Devbook je napsaný na jednoduchém MVC frameworku v PHP, pro práci s databází používá knihovnu DiBi, pro parsování článků používá knihovnu Texy!, pro zvýrazňování zdrojových kódu FSHL, dále používá další množství menších knihoven pro práci s obrázky, textem a podobně. Když bychom chtěli na devbook přidat např. výpis dat do tabulky s řazením, nebudeme zbytečně psát vlastní datovou tabulku, ale použijeme další hotovou knihovnu, kterou někdo vyrobil.

Tyto knihovny, se kterými v aplikaci pracujeme, pocházejí od různých autorů (výrobců). Když nějaký výrobce píše nekvalitní nebo nestandardní kód, může být problém jeho knihovnu použít nebo může její použití dokonce rozbít nějakou jinou část naší aplikace. Standardy samozřejmě nejsou dobré jen pro výrobce knihoven, ale i pro nás, abychom mohli na naší práci stavět u dalších projektů, které budou postavené třeba na jiném frameworku.

Jak se aplikace stále zvětšují a stále se zvyšuje potřeba použití knihoven, zvyšovala se i potřeba nějakého jednoho společného standardu, který by zajistil, že do sebe knihovny (části naší stavebnice) budou správně pasovat.

PHP Framework Interop Group

Právě problém chybějícího standardu pro PHP řeší PHP Framework Interop Group. Jedná se o sdružení programátorů nejvýznamnějších frameworků pro PHP, kteří vytvořili soubor několika standardů a dobrých praktik, jak by měl PHP kód vypadat. Sdružení vzniklo na konferenci php|tek v roce 2009 a v současnosti je jeho členy bez mála 50 autorů významných projektů.

Ačkoli se nejedná o oficiální PHP standard, dodržují ho tak významní hráči, že ho můžeme za oficiální považovat a je také možné, že se oficiálním jednou stane. Členy PHP-FIG jsou totiž např. vývojáři frameworků: Symfony 2, Zend Framework, PEAR, Doctrine, CakePHP, phpBB, Joomla a další.

PHP Specification Request (PSR)

PHP-FIG vydala již několik standardů a každý se týká jiné problematiky. Jednotlivé standardy jsou pojmenované jako PSR-N, kde N je číslo standardu. Číslování začíná od 0. Každý standard je rozdělený do několika části a podčástí pomocí nadpisů a podnadpisů. Standardy jsou velmi jednoduché, věcné a jednoznačné. Sama skupina používá pro zápis standardů doporučení RFC 2119, které pomocí slov jako "musíte", "nesmíte", "je vyžadováno" a podobně zajistí maximální srozumitelnost a jednoznačnost celé specifikace (originál doporučení je ke zhlédnutí zde: http://www.ietf.org/rfc/rfc2119.txt, jednotlivé standardy potom zde: http://www.php-fig.org/).

PSR-1

Standard PSR-0 prozatím přeskočíme a začneme rovnou PSR-1, který je úplným základem specifikace. Předepisuje jak správně používat PHP direktivu a jak pojmenovávat třídy a jejich prvky. Pojďme se na něj podívat. Standardy se budu snažit překládat co nejpřesněji, ale občas vynechám nějaké redundantní pasáže, jako shrnutí a podobně.

Soubory

Standard předepisuje jak pracovat s PHP soubory a to v následujících bodech.

PHP tagy

V PHP souborech se MUSÍ používat pouze dlouhé tagy <?php nebo krátké echo <?=.

<?= není short tag, ačkoli si to lidé často chybně myslí, a je naprosto bezpečné ho používat. Naopak bychom neměli používat jen <?, což je short tag a není zaručeno, že je server nastaven tak, aby ho zpracoval.

Kódování

Všechny PHP soubory MUSÍ být kódovány pouze v UTF-8 bez BOM.

O samotném UTF-8 je jistě zbytečné se rozepisovat. BOM je zkratka Byte Order Mark (označení pořadí bajtů). Jedná se o dobrovolný znak na začátku souboru, který specifikuje zda jsou použity pro uchování znaků 16bitová nebo 32bitová čísla. V UTF-8 nemá žádný význam a proto se často vynechává, jelikož může způsobit nepříjemné problémy.

Vedlejší účinky (Side effects)

Soubory by MĚLY pouze deklarovat symboly (třídy, funkce, konstanty,...) a nezpůsobovat žádné vedlejší účinky. Nebo by soubory MĚLY spouštět logiku, která má za následek nějaký vedlejší účinek. NEMĚLY by ale dělat obojí najednou.

Vedlejším účinkem se myslí spuštění logiky, která není přímo spojená s deklarací tříd, funkcí, konstant a podobně. Neměli bychom v jednom souboru např. deklarovat funkce a zároveň je spouštět. Snadno by se nám stalo, že bychom si chtěli takový soubor s funkcemi načíst, abychom je mohli používat a zapomněli bychom na to, že nám samotné načtení souboru již něco spustí nebo přenastaví. To je právě ten vedlejší účinek, který nás v lepším případě překvapí a v tom horším rozbije aplikaci.

Příklad takového souboru, jehož načtení vyvolává vedlejší účinky, je následující (viz standard):

<?php
// vedlejší účinek: změna ini nastavení
ini_set('error_reporting', E_ALL);

// vedlejší účinek: načtení souboru
include "file.php";

// vedlejší účinek: generování výstupu
echo "<html>\n";

// deklarace
function foo()
{
    // tělo funkce
}

Měli bychom mít tedy pouze soubory s funkcemi a třídami a potom soubory, ve kterém je načítáme a používáme. Např. takto:

Soubor matematika.php:

public function secti($a, $b)
{
        return $a + $b;
}

public function odecti($a, $b)
{
        return $a - $b;
}

...

Soubor vypocet.php:

require('matematika.php');

echo(secti(5, 6));

Deklarace logiky a její spuštění je odděleno a nedochází k nechtěným vedlejším účinkům.

Při deklaraci můžeme použít podmínky, pokud se týkají deklarace. Není to potom bráno jako vedlejší účinek:

<?php
// deklarace
function foo()
{
    // tělo funkce
}

// podmínečná deklarace *není* vedlejší účinek
if (! function_exists('bar')) {
    function bar()
    {
        // tělo funkce
    }
}

Jmenné prostory a názvy tříd

Jmenné prostory a třídy MUSÍ splňovat standard PSR-0.

O standardu PSR-0 si ještě řekneme více na konci seriálu. Nyní nám bude stačit, že předepisuje, že každá třída MUSÍ být v samostatném souboru, který je součástí nějakého jmenného prostoru. Každý jmenný prostor MUSÍ začínat názvem jeho autora/výrobce (anglicky vendor). Podívejme se na ukázku třídy z devbooku.

Ukázka pro PHP 5.3 a novější:

<?php
namespace Devbook\Clanky\Modely;

class SpravceClanku
{
        // ...
}

Devbook je právě onen vendor, všechny jeho třídy musí být ve jmenném prostoru, který začíná názvem vendora. Naopak knihovny, které devbook používá, jsou v prostorech jejich vendorů, protože jsou to samostatné komponenty, které nejsou součástí devbooku (vendora Devbook).

Kód napsaný pro starší PHP 5.2, které nepodporovalo jmenné prostory, BY MĚL používat podtržítkovou notaci v názvech tříd, která jmenné prostory nahradí:

<?php

class Devbook_Clanky_Modely_SpravceClanku
{
        // ...
}

Třídní konstanty, vlastnosti a metody

Pojďme se podívat na to, jak bychom měli správně zapisovat třídní prvky. Když budeme hovořit o třídách, budeme myslet i rozhraní nebo traits.

Konstanty

Třídní konstanty MUSÍ BÝT deklarovány velkými písmeny a s podtržítky.

Příklad ze standardu:

<?php
namespace Vendor\Model;

class Foo
{
    const VERSION = '1.0';
    const DATE_APPROVED = '2012-06-01';
}
Vlastnosti

Od pojmenování vlastností (atributů) se PSR-1 záměrně distancuje. Je to z toho důvodu, že by jinak rozbila velké množství starších projektů. Hlásá, že bychom měli používat buď $StudlyCaps, $camelCase nebo $under_score. Nicméně určitě po vzoru Javy nepoužívejte nic jiného než $camelCase.

Jakoukoli konvenci zvolíte, MĚLI BYSTE zůstat konsistentní v rozumném rozsahu. Tento rozsah může být na úrovni vendora, balíčku, třídy nebo metody.

Obvykle se jedné konvence držíme v rozsahu kódu celého vendoru. Neměli bychom v něm zavádět několik různých konvencí.

Metody

Názvy metod MUSÍ být deklarované v camelCase().

Zde je standard velmi striktní a to je dobře :)

Doufám, že vás článek zaujal a třeba jste si opravili nějaký svůj projekt. Příště budeme pokračovat ve velkém stylu a to u mnohem komplexnějšího standardu PSR-2.


 

  Aktivity (1)

Č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 (19 hlasů) :
4.894744.894744.894744.894744.89474


 


Miniatura
Všechny články v sekci
Standardy jazyka PHP

 

 

Komentáře

Avatar
Michal Žůrek (misaz):

To se skládá jenom ze 4 standartů?

Odpovědět 20.4.2014 14:07
Nesnáším {}, proto se jim vyhýbám.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Michal Žůrek (misaz)
David Čápka:

I s tou nulou je jich nyní 5. Dvojka je docela dlouhá, jinak jsou krátké.

Odpovědět 20.4.2014 15:14
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
debeneesse
Člen
Avatar
debeneesse:

Super článek a velmi vhodné téma pro tutoriál, děkuji. Akorát jsem tu opět narazil na ty short tagy. Je to věc pomíjivá pro začátečníky, protože ti netvoří multiplatformní aplikace k redistribuci, každopádně říkáte, že <?= není short tag. Já se dočetl, že to není short tag, ale zkratka pro kód <? echo ... ?>, z toho mi vychází, že to bezpečné není. Přiznám se, že u tohohle si nejsem úplně jistý a rád bych si v tom jasno udělal.

 
Odpovědět 5.3.2015 22:24
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na debeneesse
David Čápka:

Je to naprosto bezpečné používat jak je napsáno v článku.

Odpovědět  +1 7.3.2015 10:53
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Kuroaku
Člen
Avatar
Kuroaku:

Jak skupina sama říká, jedná se jen o doporučení standardů, nikoli o standardy.
Co se syntaxe týče, tak ten dokument je identický s tím, co doporučují tvůrci php. Jediným rozdílem je lowercase namísto uppercase u true, false a null.
Jinak mají ta doporučení zbytečně složitý jazyk či api. Http pro mě vždy bylo jednoduše požadavek a odpověď, případně session manager. Víc není třeba, i když je cache aplikovaná na http úrovni pro jednotlivé části stránky. Cache má zbytečně složitou angličtinu (už vydali novou, zjednodušennou verzi).
Ovšem největší chyba je v návrhu cache. Na co ukládat null? Díky tomu je zapotřebí ověřovat, zda hledaná data existují namísto vrácení null jakožto neexistující hodnoty v getu. Z čehož plyne několik problémů. Musí se zajistit atomicita mezi použitím has a get, což je spousta práce navíc u sql, filesystému i čehokoli jiného. Data se tahají dvakrát, namísto jednou, nebo se musí použít ještě jedna vnitřní cache. Zpomalíte běžící kód, koledujete si o rozbití dat a nejspíš zpomalíte i konkurenční requesty. To vše jen kvůli null.

Odpovědět 5. listopadu 19:52
Třikrát přemýšlej, dvakrát piš a debug a testy nebudou zapotřebí.
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 5 zpráv z 5.