PHP 9.0
PHP 9.0 je zatím v počáteční fázi plánování a zatím nemá pevné datum vydání. Ve skutečnosti vývojáři jádra očekávají, že se PHP 8.5 a 8.6 dočkáme ještě před příchodem verze 9.0. Jinými slovy, vývoj jazyka je postupný, ale diskuse a RFC již formují směr, kterým se PHP 9.0 bude ubírat. Důraz je kladen na odstranění výstředností a zastaralých chování, aby byl kód PHP předvídatelnější a robustnější. Jedním z návrhů je například zakázat podivné chování, kdy se inkrementuje řetězec jako např. 'a9' produkuje 'b0'; místo toho PHP 9.0 vyhodí chybu TypeError. Podobně budou tichá varování (např. z neserializace) povýšena na výjimky a zastaralé funkce budou nakonec odstraněny.
PHP 9.0 - datum vydání
Komunita PHP internals zatím neoznámila pevné datum vydání PHP 9.0. Nicméně na základě typické frekvence vydávání hlavních verzí PHP (zhruba každé 2-3 roky).
Klíčové funkce PHP 9.0
PHP 9.0 přináší několik zásadních změn. Každá z níže uvedených funkcí je podpořena aktivními RFC a komunitní diskusí; zde je technicky vysvětlíme a ukážeme příklady starého a nového chování.
1. Předvídatelný nárůst/pokles (++/--) Chování
PHP má za sebou historii překvapivých výsledků v oblasti ++ a -- provozovatelé. V PHP 8.x inkrementace řetězce nebo booleanu tiše převádí typy. Například:
$foo = 'a9';$foo++;echo $foo; // PHP 8.x outputs: "b0"
V PHP 9.0 to bude hodit a TypeError místo toho. Podobně přísněji se bude chovat inkrementace booleanů nebo prázdných řetězců. Například:
$bar = true;$bar++;var_dump($bar); // PHP 8.x: bool(true), PHP 9.0: int(2)
a
$baz = '';$baz--; // In PHP 8.x this yields int(-1), but in PHP 9.0 it will throw a TypeError.
Tyto změny jsou součástí dokumentu RFC "Cesta ke zdravějšímu nárůstu". Cílem je vytvořit ++/-- předvídatelnější. Pod PHP 9.0:
- Už žádné implicitní obalování řetězců (
'z'++or'a9'++se v tichosti nepřevrátí). - Booleans a
nulljsou považovány za číselné: inkrementacetruese stává2spíše nežtrue. - Prázdné řetězce se již nestávají čísly (prázdný řetězec)
''se automaticky nepřevede na 0; při převodu dojde k chybě). - Nová pomocná funkce
str_increment()je v případě potřeby zavedeno chování starého řetězce.
Tyto aktualizace odstraňují mnoho nenápadných chyb. V praxi to znamená, že pokud váš kód spoléhal na podivné automatické doplňování, budete jej muset aktualizovat. V opačném případě většina moderních kódových základen jednoduše najde ++/-- bezpečnější a důslednější.
RFC: Cesta ke zdravějším operátorům Increment/Decrement
2. Výjimky pro chyby neserializace
V PHP 8.x je volání unserialize() na neplatná data vydá varování a vrátí false. V PHP 9.0 je tato funkce změněna tak, že se vyhodí výjimka. Například:
// PHP 8.x:$result = unserialize("invalid"); // emits a warning: "Error at offset 0", returns false // PHP 9.0:$result = unserialize("invalid"); // throws UnserializationFailedException
To je dáno doporučením RFC "Improve unserialize() error handling". Převedením těchto varování na UnserializationFailedException, PHP 9.0 umožňuje jednoznačnější a bezpečnější zpracování chyb. Vývojáři nyní mohou používat try/catch v okolí unserialize(), čímž se vyhnete skrytým problémům:
try { $obj = unserialize($data);} catch (UnserializationFailedException $e) { // handle error gracefully}
Tato změna také souvisí s Postupné vyřazování Serializable RFC: v PHP 9.0 je stará verze Serializable bude odstraněno a užitečné soubory používající starší serializační formát "C" budou odmítnuty. Stručně řečeno, serializace PHP se zpřísní a zmodernizuje.
RFC: Vylepšení zpracování chyb funkce unserialize() · Postupné vyřazování Serializable
3. Zjednodušené signatury funkcí
Některé vestavěné funkce a metody budou rozděleny nebo přejmenovány z důvodu přehlednosti. Pozoruhodným příkladem je přetížené podpisy. Vezměte si array_keys():
// PHP 8.x:$keys = array_keys($myArray); // all keys$keys = array_keys($myArray, 'value', true); // only keys with matching value // PHP 9.0 (example RFC):$keys = array_keys($myArray);$keys = array_keys_filter($myArray, 'value', true);
PHP 9.0 zde zavádí novou funkci (např. array_keys_filter) pro druhý režim, místo aby jedna funkce vykonávala dvě úlohy. Dalším příkladem je DatePeriodkonstruktoru:
// PHP 8.x:$period = new DatePeriod($start, $interval, $end);$period = new DatePeriod('R4/2012-07-01T00:00:00Z/P7D'); // PHP 9.0:$period = new DatePeriod($start, $interval, $end);$period = DatePeriod::createFromISO8601String('R4/2012-07-01T00:00:00Z/P7D');
Výhodou je přehlednější API: každá funkce dělá jednu věc, což usnadňuje pochopení kódu. Tento přechod bude probíhat postupně v PHP 8.x (nové funkce ve verzi 8.3, varování o zastarání ve verzi 8.4, odstranění ve verzi 9.0).
RFC: Odstranění funkcí s přetíženými signaturami · Odebrání pro PHP 8.1
4. Žádná autovivifikace (pole z False)
PHP "autovivifikace" polí, která automaticky změní pole false or null do pole při připojování do pole bude v PHP 9.0 zakázáno. Například:
$arr = false;$arr[] = 2; // PHP 8.x: converts $arr to [2]
V PHP 9.0 to bude chyba venku:
$arr = false;$arr[] = 2; // PHP 9.0: Error - cannot use a scalar as an array
Tato změna pochází z RFC "Deprecate autovivification on false". Protože ostatní skaláry, jako např. true or 0 již chyba, takže false se chová stejně odstraňuje zvláštní případ. Odstraňuje běžnou chybu, kdy se neplatná data v tichosti změnila na pole. V praxi by nyní měl kód explicitně inicializovat pole (např. $arr = []) před připojením, místo aby se spoléhal na tuto zvláštnost.
RFC: Odstranit autovivifikaci na false
5. Zjednodušená interpolace řetězců
PHP 9.0 zjednoduší způsob vkládání proměnných do řetězců. V současné době PHP podporuje několik syntaxí:
- Dvojité uvozovky s jednoduchou proměnnou:
"$foo" - Závorky kolem proměnné:
"{$foo}" - Rovnátka po dolaru:
"${foo}" - Proměnné v řetězcích:
"${expr}"
PHP 9.0 bude odstranit "závorky za dolarem" a syntaxe proměnná-proměnná (poslední dvě výše uvedené). To znamená, že kód jako:
$foo = "world";echo "Hello ${foo}"; // This will cause an error in PHP 9.0
již nebude povoleno. Zůstanou pouze standardní formuláře:
echo "Hello $foo"; // OKecho "Hello {$foo}"; // OK
RFC "Deprecate ${} "interpolace řetězců" vysvětluje, že ${} syntaxe je matoucí a zřídkakdy potřebná. Jejím odstraněním podporuje PHP jednotný a přehlednější styl interpolace. Tím se také zamezí jemným problémům s rozborem složitých řetězců.
RFC: Odstranění interpolace řetězců ${}
6. Varování se stávají fatálními chybami
Některá varování v PHP 8.x budou v PHP 9.0 převedena na chyby. Zejména odkazování na nedefinované proměnné nebo vlastnosti, které dnes vydává varování, bude místo toho vydávat hlášku fatální chyba. Například:
// PHP 8.x:echo $undefinedVar;// Warning: Undefined variable $undefinedVar // PHP 9.0:echo $undefinedVar;// Fatal error: Uncaught Error: Undefined variable '$undefinedVar'
Tato změna (prostřednictvím dokumentů RFC "Undefined Variable Error Promotion" a "Undefined Property Error Promotion") znamená, že laxní kódovací vzory budou porušeny. Záměrem je včas zachytit chyby, např. překlepy nebo zapomenuté inicializace, a nenechat je proklouznout. Chybami se mohou stát i další varování, takže vývojáři musí kód spouštět s kódem E_ALL a opravit případná upozornění. PHP 9.0 zkrátka podporuje čistší a bezchybný kód ve výchozím nastavení.
RFC: Propagace chyby nedefinované proměnné · Propagace chyby nedefinované vlastnosti
7. Odstranění zastaralých funkcí
Všechny funkce, které byly v PHP 8.1-8.4 odstraněny, budou v PHP 9.0 odstraněny. To znamená, že aktualizace staršího kódu je kritická. Mezi příklady patří:
- Konstrukce starého typu (konstruktory tříd ve stylu PHP 5.x již dávno neexistují).
- Odebrání GMP a specifických rozšíření (např. postupné zrušení některých rozšíření).
- Další chování pole/řetězce jako výše uvedená autovivifikace a interpolace řetězců.
Přesný seznam pochází z RFC pro PHP 8.1, 8.2, 8.3 a 8.4 deprecations. V praxi to znamená, že všechna varování o depreciaci, která se zobrazí v PHP 8.3, je nyní nutné vyřešit před přechodem na verzi 9.0. Toto vyčištění zachovává moderní PHP, ale znamená, že zlomové změny pro starší kód. Všechny zastaralé funkce, dynamické vlastnosti (pokud byly spuštěny) a starší chování konečně zmizí.
Odkazy na RFC: Odebrání pro PHP 8.1 · Odebrání pro PHP 8.2 · Odebrání pro PHP 8.3 · Odebrání pro PHP 8.4 · Odebrání pro PHP 8.5 · Odebrání pro PHP 8.6
8. Odstranění částečně podporovaných výzev k úhradě
Některé volatelné formáty byly v minulosti akceptovány funkcemi jako např. call_user_func() a is_callable(), ale nikdy nebyly plně podporovány $callable() syntaxe volání. Plánuje se, že PHP 9.0 odstranění podpory pro tyto "částečně podporované volání", jako jsou:
"self::method","parent::method","static::method"["self", "method"],["parent", "method"],["static", "method"]
Kód, který se spoléhá na tyto vzory, bude muset přejít na plně podporované callables (např. Foo::class . "::method", [Foo::class, "method"], nebo [new Foo(), "method"]).
RFC: Odstranění částečně podporovaných volání
9. Přísnější explicitní obsazení (už žádné "rozmazané" obsazení)
Explicitní obsazení v jazyce PHP historicky umožňovalo konverze, které v tichosti informace o vyřazení (například otočení "123abc" na 123). Novější návrh to zpřísňuje tím, že odstranění fuzzy castů v PHP 8.6 a vytváří je hodit TypeError v PHP 9.0.
Příklady chování, na které se RFC zaměřuje:
// Partial string conversions (currently succeed by discarding trailing data)(int) "123abc"; // PHP 9.0: TypeError(float) "12.5foo"; // PHP 9.0: TypeError // Scalar-to-object casts (currently create a stdClass wrapper)(object) 42; // PHP 9.0: TypeError(object) "hello"; // PHP 9.0: TypeError
Cílem je sladit chování explicitního obsazení s validačními pravidly, která se již používají pro typované parametry v režimu bez omezení.
RFC: Odstranění fuzzy a null castů
10. Implicitní koercionace boolů na řetězce se stává chybou typu (TypeError)
Implicitní převod logických symbolů na řetězce je považován za pravděpodobný vzor chyby (false se stává '', true se stává '1'). Navrhuje se emitovat E_DEPRECATED nejprve a pak zvýšit na TypeError v PHP 9.0.
Například:
$flag = false;echo "Value: " . $flag; // PHP 9.0: TypeError (after deprecation period)
RFC: Odstranit vynucení boolean na řetězec
RFC: Zajistit, aby konstruktory a destruktory vracely void
11. PHP 9.0 opouští 32bitové sestavení
Existuje aktivní návrh na v příští verzi PHP 8.x zrušit podporu 32 bitů. a úplné odstranění 32bitových sestavení v PHP 9.0. To znamená, že PHP 9.0 již nebude možné sestavit ani spustit v 32bitovém prostředí.
Důvodem jsou především trendy platforem a dlouhodobá 32bitová omezení (např. limity 2 GB a problémy s rozsahem časových značek).
RFC: Zahození 32bitových sestavení
12. Vyčištění introspekce enumů (get_declared_enums() a class_exists() sémantika)
Návrh přidává nový get_declared_enums() a zpřísňuje význam slova "třída" v pomocných nástrojích ve stylu reflexe:
class_exists()by bylo zastaralé pro enumy v PHP 8.x a vrátitfalsepro enumy v PHP 9.0.get_declared_classes()by v PHP 9.0 přestal vracet enumy.
enum Status { case Draft; } var_dump(enum_exists(Status::class)); // truevar_dump(class_exists(Status::class)); // PHP 9.0: false
RFC: Přidání funkce get_declared_enums()
13. Dynamické vlastnosti se stávají chybami (pokud nejsou výslovně povoleny)
V jazyce PHP se při přiřazení nedeklarované vlastnosti historicky vytváří příznak dynamická vlastnost tiše. Tato funkce je nyní na cestě k odstranění: byla zrušena v PHP 8.2 a v PHP 8.2. PHP 9.0 to vyhodí Error pokud to třída výslovně nezvolí.
class User { public string $name;} $user = new User;$user->nane = "typo"; // PHP 8.2: deprecation, PHP 9.0: Error
Aby bylo možné zachovat záměrné dynamické vlastnosti, zavádí PHP #[AllowDynamicProperties] (a stdClass je nadále povoluje). V opačném případě deklarujte vlastnost, použijte __get()/__set()nebo ukládat externí data do WeakMap.
RFC: Vyřazení dynamických vlastností
14. null k nenulovatelným interním skalárním argumentům Vyhodí TypeError
Historicky se mnoho interní funkce v PHP by akceptovaly null pro nenulovatelné skalární parametry ve slabém módu a tiše je donutit (často k "", 0, nebo false). Toto chování bylo v PHP 8.1 odstraněno a stává se z něj TypeError v PHP 9.0, což odpovídá chování funkcí v uživatelském prostoru.
// Example behavior change:strlen(null); // PHP 8.1+: E_DEPRECATED, PHP 9.0: TypeError
Praktické řešení spočívá v explicitním zpracování null před voláním funkce (nebo zadejte výchozí hodnotu), místo abyste se spoléhali na implicitní vynucení.
RFC: Odstranit předávání null nenulovatelným argumentům interních funkcí
15. Odstranění utf8_encode() a utf8_decode()
V PHP 9.0, utf8_encode() a utf8_decode() jsou odstraněny. Kódové báze, které je stále používají, by měly přejít na podporovaná API pro převod kódování (RFC zdůrazňuje mb_convert_encoding() jako primární náhrada, přičemž UConverter::transcode() a iconv() jako alternativy).
RFC: Odstranění utf8_encode a utf8_decode
16. Odstranění ID relací GET/POST, use_trans_sida SID Konstantní
Dřívější schopnost PHP šířit ID relace prostřednictvím parametrů GET/POST (a automaticky přepisovat adresy URL prostřednictvím use_trans_sid) je na cestě k odstranění. Související nastavení INI a SID jsou zastaralé (cílené v PHP 8.4) a jsou určeny k tomu. odstraněno v PHP 9.0.
Tím se manipulace s relacemi výrazně posouvá směrem k relacím založeným na souborech cookie (nebo k explicitním náhradním řešením na úrovni aplikace, pokud soubory cookie nelze použít).
17. Fuzzy Scalar Casts Stát se TypeError (Návrh)
Novější návrh (v současné době v jednání) se zaměřuje na "fuzzy" obsazení - případy, kdy explicitní obsazení zahazuje informace (například částečné parsování číselných řetězců) nebo vytváří libovolné struktury (například obsazení skalárů do tvaru (object)). RFC navrhuje, aby byly tyto případy v PHP 8.6 odstraněny a převedeny na případy TypeError v PHP 9.0.
Mezi příklady dotčených vzorů patří:
(int) "123abc"; // currently truncates to 123(float) "12.5foo"; // currently truncates to 12.5(object) 42; // currently produces stdClass with a scalar property
Pokud by byl tento návrh přijat, dále by se omezily "překvapivé" konverze a přizpůsobily by se odlovy pravidlům validace, která se již používají pro parametry se slabým typem.
RFC: Odstranit fuzzy skalární obsazení
Jak se připravit a migrovat
Vzhledem k těmto změnám by se vývojáři PHP měli začít připravovat již nyní. Mezi hlavní doporučení patří:
- Povolit přísné hlášení chyb. Spusťte svůj kód v PHP 8.3+ pomocí
error_reporting(E_ALL)a opravit všechna varování a upozornění. Všechna varování o zastaralosti (např. staré konstruktory, podivnosti s poli/řetězci) by měla být okamžitě vyřešena. - Přepracování pro předvídatelnost typů. Nespoléhejte se na implicitní konverze typů. Například nezáviďte na
falsese zázračně stane polem. Inicializujte proměnné explicitně a preferujte typově bezpečný kód. - Zachycení chybné unserializace. Audit všech volání na
unserialize()a zabalit je dotry/catchproUnserializationFailedException. Odstranění používáníSerializablepokud je to možné, protože bude postupně vyřazen. - Sledujte diskuse RFC. Zůstaňte aktivní v interních a komunitních kanálech PHP. Jazyk se neustále vyvíjí a je třeba mít přehled o přijatých RFC (prostřednictvím webových stránek). wiki.php.net/rfc) vám pomůže zjistit, co vás čeká.
- Testování na předběžných verzích. Jakmile se objeví alfa verze PHP 9.0, okamžitě spusťte své testovací sady a aplikace. Včasné odhalení nekompatibility je mnohem snazší než po vydání.
- Sledování rámců a knihoven. Aktualizujte na nejnovější verze frameworků (Laravel, Symfony atd.), které podporují PHP 9.0, jakmile budou k dispozici. Autoři knihoven pravděpodobně vydají aktualizace kompatibility, jakmile se verze 9.0 stabilizuje.
Dodržení těchto kroků zajistí hladší průběh upgradu. Zdroje zdůrazňují zejména oprava všech varování o zastaralosti a použití explicitního zpracování chyb aby se přísnost PHP 9.0 stala vlastností, nikoli překvapením.
Dopad na ekosystém PHP
Komunita PHP a hlavní dílčí komunity (Symfony, Laravel, WordPress atd.) se budou muset přizpůsobit změnám v PHP 9.0. Žádný z našich zdrojů výslovně neuvádí podrobnosti o aktualizacích specifických pro daný rámec, ale můžeme extrapolovat:
- Moderní frameworky (Laravel, Symfony atd.) se obvykle zaměřují na nejnovější verze PHP. Pravděpodobně již píší kód, který předpokládá striktní typy a explicitní zpracování. Tyto frameworky budou pravděpodobně rychlé osvojení PHP 9.0 aktualizace interního kódu za účelem odstranění zastaralých funkcí a využití nových funkcí/API.
- WordPress je konzervativnější a podporuje mnoho starších verzí PHP kvůli zpětné kompatibilitě. Jádro WordPressu si proto pravděpodobně vezme čas na přípravu. Můžeme očekávat, že WordPress 7.0 (nebo jiná významná verze) zvýší své minimální požadavky na PHP. Zásuvné moduly a témata bude třeba otestovat: veškeré spoléhání na dynamické vlastnosti nebo automatické oživování musí být opraveno.
- PHP-FIG a standardy komunity: Standardy PSR a sdílené knihovny mohou být aktualizovány tak, aby odrážely postupy PHP 9.0.
- Vzdělávání a adopce: Komunita bude vytvářet průvodce (jako je tento) a migrační nástroje (jako jsou sady Rector), které pomohou projektům s upgradem.
Závěr
PHP 9.0 slibuje, že bude čistší a předvídatelnější jazyk než kdykoli předtím. Plánované změny předvídatelných operátorů, chyb založených na výjimkách, zjednodušené syntaxe a odstranění staršího chování sice přinášejí zlomové změny, ale v konečném důsledku posilují PHP pro budoucí vývoj. Pokud vývojáři přijmou opatření již nyní (oprava depreciací, refaktorizace kódu, zapojení do RFC), mohou si zajistit hladký přechod. Konečným výsledkem budou kódové základny PHP, které při skutečných chybách rychle selhávají, což povede k robustnějším webovým aplikacím. Jak shrnuje jeden zdroj: "PHP 9.0 se stává verzí, která upřednostňuje předvídatelnost, přísnější ošetření chyb a čistší syntaxi," což z jazyka dělá modernější a přívětivější pro vývojáře.