Reklamní agentura Zobrazit menu

 

Všechny články

 

Vedu hradecké vývojové centrum, kde mám na starosti řízení týmu a strategii vývoje Meebu. Ve volném čase rád sednu k dobré knize nebo deskovce.

PHP 8: Změny a novinky, na které se nejvíc těším

Autor: Dominik Žilka

Publikováno: 26.11.2020

 

Dnešní den se zapíše do historie. Dobře, asi ne úplně do českých učebnic dějepisu (přeci jenom v datu chybí ta osudová osmička), ale pro skupinu bastlerů používajících nejodpornější programovací jazyk světa (hejtovaný zejména lidmi, co ho naposledy viděli před 15 lety nebo vůbec), to významné datum bezpochyby je. Ano, řeč je o PHP 8, které dnes oficiálně vyšlo. Vzhledem k tomu, že v Meebiu se k PHP hrdě hlásíme a je to náš denní chleba, těšíme se velice. Nová major verze toho přináší opravdu hodně, dovolil jsem si tedy vybrat a krátce představit to, podle mého soudu, nejzajímavější.

Definice atributů třídy v konstruktoru

První z novinek, kterou si představíme, je možnost definování atributů třídy až (a pouze) v konstruktoru. To se hodí zejména při vytváření tříd, které slouží pouze jako "obálky" pro hodnoty (v angličtině simple value objects). Pojďme si to demonstrovat na jednoduchém příkladu. Mějme třídu Person, která reprezentuje osobu se třemi atributy: name, surname a age. Všechny atributy definuji jako public, což samozřejmě z hlediska OOP není úplně v pořádku, ale věřím, že pro účely této ukázky mi to laskavý čtenář promine. Její definice v PHP 7.4 může vypadat následovně:

class Address {
    public string $name;
    public string $surname;
    public int $age;

    public function __construct(string $name, string $surname, int $age){
        $this->name = $name;
        $this->surname = $surname;
        $this->age = $age;
    }
}

Jak trefně uvádí autor RFC, Nikita Popov, při tvorbě simple value objectu se v kódu jednotlivé atributy (a jejich hodnoty) postupně objeví minimálně 4x, což je opravdu docela dost psaní. Nová verze přichází se zkrácenou variantou zápisu, která vypadá takto:

class Adress {
    public function __construct(
        public string $name = '',
        public string $surname = '',
        public int $age,
    ){}
}

Atributy se definují pouze jednou, a to v hlavičce konstruktoru. Zbytek černé práce už vykoná interpreter. Docela šikovné, že? Osobně největší přínos vidím v tom, že programátor (čili tvor od přírody líný :-)) bude v menším pokušení si data ukládat do stdClass nebo, nedejbože, do asociativního pole a vytvoří si vlastní třídu.

Koncová čárka ve výčtu parametrů?

Možná jste si povšimli na příkladu výše, že jsem zapomněl ve výčtu parametrů konstruktoru za posledním parametrem age čárku. To samozřejmě v PHP způsobí chybu. Teda vlastně spíše způsobovalo... Od verze 8 je již tato syntaxe naprosto v pořádku (čímž se sjednotila syntaxe například s poli). Je to sice detail, ale musím říct, že jsem za něj rád, protože se mi tato chyba nejednou přihodila.

JIT

Metoda JIT (z anglického Just-in-time) představuje způsob, jak lze celkem rapidně zvýšit výkon programu. Nejde o novinku (první implementace, pokud Wikipedie nelže, pochází už z roku 1960), tento koncept je dobře znám z Javy nebo C#. V principu jde o to, že tzv. monitor projde zdrojový kód a vyhodnotí ty části, které jsou využívany opakovaně a označí je příznakem. Tyto fragmenty následně přeloží rovnou do strojového kódu optimalizovaného pro konkrétní instrukční sadu daného procesoru (čili zkompiluje) a pokaždé, když se volá daný kus kódu, tak použije tyto "cachované" instrukce namísto toho aby kompiloval každý řádek zdrojového kódu (nejprve do intermediate kódu, pochopitelně). Dá se říct, s trochou nadsázky, že JIT kompilace kombinuje výhody interpretovaných jazyků s jazyky kompilovanými. V případě PHP to tedy bude znamenat, že Zend VM (interpret jazyka) některé části rovnou zkompiluje do strojového kódu a dále je již nebude znovu intepretovat do OP instrukcí.

Samozřejmě celá problematika je daleko složitější, jsou o ní popsány stohy prací a správná implementace je umění. Pro představu to snad bude stačit (dále radši nerozvádím, zájemcům nabídnu skvělý článek z thePHP Website). V praktickém důsledku by to tedy mělo přinést větší výkon aplikací. Samozřejmě reálné dopady ukáže teprve praxe a je otázkou, na kolik jsou webové aplikace, doména PHP, vhodný pro takovou optimalizaci a určitě ani zdaleka nelze čekat takové zrychlení jako mezi verzemi 5 a 7. Myslím, ale že minimálně do budoucna je to dobrý příslib, který otevře PHP další obzory.

Abych trochu proložil suchopárný text, přikládám video jednoho z vývojářů PHP, Zeeva Suraskiho, který ukazuje rozdíl ve výkonu při generování fraktálu. Samozřejmě, ponechávám stranou vhodnost použití PHP pro operaci toho typu.

Nové vestavěné funkce

PHP 8 také rozšiřuje paletu nativních funkcí jazyka, vypíchnu alespoň 4 nové kousky.

str_contains

Funkce, která zkontroluje, jestli string obsahuje jiný string, vrací true nebo false. Vzhledem k tomu, o jak častý use-case se jedná, překvapuje mě, jak dlouho taková funkce v jazyku chyběla. Její syntaxe je naprosto triviální:

str_contains("abc", "a"); // vrací true
str_contains("abc", "d"); // vrací false

// a co prázdný string?
str_contains("abc", "");  // vrací true
str_contains("", "");     // vrací true

Konečně tedy nebudeme muset používat nepříliš intuitivní strpos, strstr nebo dokonce count(explode). Jasně, netvrdím, že se jedná o přelomovou změnu, ale jsem si jist, že nejednomu začátečníkovi ušetří troch vzteku.

str_starts_with a str_ends_with

Další šikovná funkce (respektive dvě), které usnadní práci s řetězci, konkrétně ověří, jestli string začíná (respektive končí) jiným stringem (čili už žádné další využívání funkce substr k tomuto účelu). Opět vrací pouze true nebo false. Použití vypadá takto:

str_starts_with("abc","a") // vraci true
str_starts_with("abc","c") // vrací false
str_starts_with("abc","") // vrací true

Jsem rád, že výše představené funkce drží notaci s podtržítky. Kéž bychom se jednou dočkali trochu většího pořádku v pojmenovávání nativních funkcí (ne jako v případě strlen například...).

get_debug_type

Funkci, kterou oceníte především při debuggingu (podle názvu překvapivé, že?) a která vypíše datový typ proměnné. Její síla spočívá v tom, že si poradí jak s třídami, tak s primitivními typy, a to bez využití dalších konstrukcí a funkcí. Na rozdíl od již existující funkce gettype, vrací typy, tak jak se v PHP označují (čili vrátí místo integer hodnotu int). Dovolím si přiložit ukázku z příslušného RFC:

if (!($bar instanceof Foo)) {
    // this shows the most simple of patterns, to get the real type an assoc array
    // must be present to convert long-form "integer" into int etc.
    throw new TypeError('Expected ' . Foo::class . ' got ' . (is_object($bar) ? get_class($bar) : gettype($bar)));
}

// would become
if (!($bar instanceof Foo)) {
    throw new TypeError('Expected ' . Foo::class . ' got ' . get_debug_type($bar));
}

Stabilní třídicí algoritmy

Možná jste se s tím také setkali. Použijete některou z vestavěných funkcí pro řazení (např. prvků pole) podle hodnoty a pokud mají dva prvky stejnou hodnotu, jejich pořadí se při opakovaných provedení mění. Takovému řazení se říká nestabilní. Pojďme si to opět demonstrovat na příkladu. Použijeme funkci asort, která seřadí prvky v poli se zachováním jejich indexů.

// hodnota $sortedArray z nestabilního asortu bude
['b' => 1, 'c' => 1, 'd' => 3, 'a' => 5];
// nebo také
['c' => 1, 'b' => 1, 'd' => 3, 'a' => 5];

Nic moc, což? Naštěstí v novém PHP je tento problém již vyřešen a výstup bude vždy stejný, čili stabilní:

// hodnota $sortedArray stabilního asortu bude vždy
['b' => 1, 'c' => 1, 'd' => 3, 'a' => 5];

Konstrukce match

Nová verze přináší také novou konstrukci match, která se dá nadneseně označit jako switch na steroidech. Umí vracet hodnoty a je rozhodně méně ukecaná. Mějme tedy následující switch (drze se přiznávám ke krádeži příkladu z blogu stitcher.io).

switch ($statusCode) {
    case 200:
    case 300:
        $errorMessage = null;
        break;
    case 403:
        $errorMessage = 'forbidden';
    case 404:
        $errorMessage = 'not found';
        break;
    case 500:
        $errorMessage = 'server error';
        break;
    default:
        $errorMessage = 'unknown status code';
        break;
}

S použitím match můžeme to stejné zapsat následovně:

$errorMessage = match($statusCode){
    200, 300 => null,
    403 => 'forbidden',
    404 => 'not found',
    500 => 'server error',
    default => 'unknow status code',
};

Jak je z příkladu dále patrné, konstrukce match nevyžaduje využití příkazu break a umožňuje spojit více větví do jedné.

Nullsafe operátor

Poslední z nových featur, u které se zastavím je nový operátor ?->. Ten rozšiřuje funkčnost klasického operátoru -> o kontrolu, jestli není získávané property nebo výstup funkce null. Pokud je hodnota null, vyhodnocování se zastaví a bude vráceno null, v opačném případě bude fungovat stejně jako operátor standardní. To zásadně zjednodušuje život (checkování null hodnot vede často k zanořování a opakování stejných kusů kódu). Přikládám opět ukázku z RFC. Mějme následující kód, který nastavuje zemi do proměnné $country z adresy uložené v session.

$country =  null;
 
if ($session !== null) {
    $user = $session->user;
 
    if ($user !== null) {
        $address = $user->getAddress();
 
        if ($address !== null) {
            $country = $address->country;
        }
    }
}
 

S novým null safe operátorem to můžeme celé podstatně zkrátit:

$country = $session?->user?->getAddress()?->country;

Tak to byly dle mého názoru ty nejzajímavější změny a novinky v PHP 8.0. Seznam je pochopitelně čistě subjektivní a vím, že jsem v něm, možná nespravedlivě, opominul zmínit další novinky (namátkou nový návratový typ mixed, nový interface Stringable nebo konsistentní type errory). Každopádně jsem velice rád, že PHP v posledních letech nebývale žije a věřím, že tento trend bude pokračovat. A kdoví, třeba se jednou dočkám i mnou vysněných enumerací. A jaké změny byste vypíchli vy a co vám v PHP nejcitelněji chybí?

 

 

 

Přidat komentář

 

Předchozí článek

Sociální sítě

 

Meebio newsletter

Přihlaste se k odběru našeho newsletteru.
Spamovat vás nebudeme - na to nemáme čas.

 

FORUM 24 Zdravotní pojišťovna ministerstva vnitra Globus Subway česká tisková kancelář Fujitsu KIA DHL