Přechod z PHP 5 na PHP 7
Jak převést staré weby na nové PHP 7, co bude potřeba upravit a co úplně předělat? Seznam nejčastěji použitých funkcí a metod a jejich případné změny.
Symfony 11.8.2015 ohlásilo, že všechny udržované větve jsou připraveny na PHP 7. První informace, která se objevila o nové verzi Laravelu 5.5 (vydáno v srpnu 2017), byla, že poběží pouze na PHP 7+. WordPress od verze 4.4 (vydáno 8.12.2015) podporuje PHP 7. Tumblr také běží na PHP 7 a napsal o tom, jak migrovali a k jakému zrychlení došlo s pěknými grafy.
Velké frameworky i CMS systémy již na PHP 7 přešly nebo jej podporují. V minulém článku jsem popsal, jak na jednom serveru fungovat s více verzemi PHP. Nic tedy nebrání případnému testu systémů pod novou verzi a následnému upgradu.
Nekompatibilita mezi verzemi
Mezi jednotlivými minoritními verzemi PHP 5 k velkým změnám nedocházelo, ale přesto tam byly. Drobných změn či úprav je samozřejmě velké množství, takže popsány jsou jen ty největší změny. Nebudu ani rozepisovat nové možnosti PHP 7.
Přechod z 5.6 na 7.0 nebo 7.1
Nejpalčivější problém budou především odebrané funkce mysql_*, ty je nyní nutné nahradit za mysqli_, které ale nemají vždy shodné chování, nebo lépe abstraktní PDO. Také došlo k odebrání mssql_* funkcí. Další na seznamu jsou ereg_* funkce, které je potřeba přepsat na preg_. U funkce preg_replace je odebrán modifikátor \e a je nutné volání nahradit funkcí preg_replace_callback.
Rovněž došlo ke změnám v chování
- Nová rezervovaná slova, která nelze použít jako názvy tříd, interface a traitů:
resource, object, mixed, numeric, void, iterable - Cyklus foreach nemění interní pointer pole, tj. kontrola pomocí funkcí current, next apod. nefunguje, jejich návratová hodnota se v průběhu cyklu nemění.
- Mnoho chyb v PHP 5 bylo konvertováno na výjimky. Ne všechny dědí z Exception, všechny ale implementují interface Throwable, viz níže.
- Chyba v konstruktoru u některých interních tříd PHP vracela NULL, nyní ve všech případech vždy vyhazuje výjimku.
- Chyba E_STRICT již neexistuje, byla překvalifikována na jiné. Konstanta ale zůstala nadeklarována, aby zápisy s touto konstantou nevyhazovaly chybu.
- Evaluace proměnných probíhá zleva-doprava, namísto starého zprava-doleva.
Změn je rozhodně velké množství, všechny jsou popsány v dokumentaci v Migrační příručce, převážně pak kapitola Zpětně nekompatibilní a Jak na chyby v PHP 7.
Ukázka zpětně kompatibilního try-catch bloku pro správnou funkčnost v PHP 5 i 7:
1 2 3 4 5 6 7 8 9 |
try{ // Kritický kód }catch (Throwable $throwable){ // Odchyceno pouze v PHP 7 }catch (Exception $exception){ // Odchyceno pouze v PHP 5 } // Při přehození pořadí catch bloků níže nebude platit slovo POUZE, // catch(Exception $e) by poté fungoval i v PHP 7 |
Přechod z 5.4/5.5 na 7.0 nebo 7.1
Vše výše uvedené a navíc:
- V JSONu musí být true, false a null malými písmeny, jinak json_decode vrací chybovou hlášku.
- Syntaxe @cesta_k_souboru již nelze použít pro upload souboru s cURL.
- Další v dokumentaci, Migrace z PHP 5.5 na 5.6 a 5.4 na 5.5
Změny mezi PHP 5.2, 5.3 a 5.4
Velké změny nastaly také při změně minoritní verze z 3 na 4. Mezi ty nejhlavnější patřilo odebrání již historického safe_mod a magic_quotes. Ostatních změn je mnoho, byly ale menší a spíše omezily akorát tvůrce prasáckých kódů.
Podobně na tom byl přechod z verze 5.2 na 5.3.
Další rezervována slova jsou
- 5.3 na 5.4: trait, callable, insteadof
- 5.2 na 5.3: namespace, goto
Že se ve verzi 5.4 kompletně odebrala možnost register_globals, která již od PHP 4.2 byla defaultně vypnutá, by mě netrápilo. Jenže jsem zjistil, že jeden nejmenovaný hosting Banán.cz má i u verzí PHP 5 tuto funkci běžně zapnutou. Pro ujasnění, tato prasárna fungovala asi takto:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// Přišel $_POST nebo $_GET požadavek, jejich výpisem by bylo toto print_r($_POST); print_r($_GET); // Výpis: array( 'firstname' => "Pavel", 'surname' => "Kutáč" ) array( 'page' => "registrace" ) // Pak při zapnutém register_globals, by byly tyto proměnné // automaticky vytvořeny a naplněny $firstname == "Pavel"; $surname == "Kutáč"; $page == "registrace"; |
Ve zkratce, pomocí POST nebo GET požadavku bylo možné vytvořit nové proměnné, a pokud je programátor dříve četl, než naplnil, šlo takto ovlivnit běh skriptu.
Přechod s WordPressem
Přechod CMS systému je vždy komplikovaný. Ne snad proto, že samotný WordPress by nějak zaostával, ostatně hned v úvodu je psáno, že od verze 4.4 je plně funkční na PHP 7. Problémem jsou pluginy a témata třetích stran.
Pokud je ale upgrade na PHP 7 nevyhnutelný, lze alespoň využít nástroje PHP Compatibility checker. Analýza je statická (linting), takže není 100% a určitě má své omezení, přesto může pomoct vychytat ty největší mouchy.
Napsat komentář