Přechod z PHP 5 na PHP 7

Tento článek (nebo jeho část) je převzat z externího zdroje. Je tedy slušností jej uvést včetně případného autora.

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 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ů:
    resourceobjectmixednumericvoiditerable
  • Cyklus foreach nemění interní pointer pole, tj. kontrola pomocí funkcí currentnext 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:

 

Přechod z 5.4/5.5 na 7.0 nebo 7.1

Vše výše uvedené a navíc:

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: traitcallableinsteadof
  • 5.2 na 5.3: namespacegoto

Ž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:

 


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 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.