Vývoj PHP 6

5. 12. 2005
Doba čtení: 7 minut

Sdílet

Sotva vyšlo PHP 5.1 a v kuchyni už se delší dobu vaří další velká verze. Skoro všichni významní vývojáři jádra PHP se 11. a 12. listopadu 2005 sešli na konferenci v Paříži a probrali, jakým směrem se má ubírat vývoj PHP 6. Derick Rethans z toho vytvořil precizní závěry a já zase nabízím jejich souhrn.

Unicode

Asi nejméně kontroverzní jsou změny v Unicode, které má být hlavní novinkou PHP 6 a o kterém už jsem stručně psal.

  • To, zda se má Unicode interně používat, nepůjde určit při každém požadavku, ale pouze v php.ini (1.1).
  • Kromě stávajících kódování bude možné určit také kódování názvů souborů, protože různé systémy používají různá kódování (1.5).
  • Novinkou pro mě je, že přestože interní kódování PHP 6 bude UTF-16, tak jeden znak bude moci zabírat dva nebo čtyři bajty (budou podporovány i znaky s kódem nad 65535). Kvůli tomu by byly operace pro přístup k jednotlivým znakům pomalé a bude pravděpodobně nutné implementovat nějakou cache (1.7). Když už to tak je, kladu si otázku, proč vlastně interní kódování nebude UTF-8, které pravděpodobně bude převažovat na vstupu a výstupu – ušetřilo by se tím mnoho zbytečných konverzí.
  • Pro chyby při převodu kódování bude vytvořena nová úroveň chyb (1.10).

Odstraněné vlastnosti

Spoustě lidí spadne kámen ze srdce a spoustě lidí se ztíží přechod na novou verzi odstraněním některých vlastností.

Zachované obraty

Některé sporné obraty naproti tomu budou zachovány:

  • Vynucení reference při volání funkce vyvolá E_STRICT místo E_NOTICE, var zůstane aliasem pro public a varování zmizí a přiřazení new referencí zůstane E_STRICT (2.4).
  • Direktiva open_basedir přežije (2.7).
  • Funkce dl bude přesunuta do SAPI, ve kterých dává smysl (momentálně CLI) (2.8).
  • Třídy nadále bude možné definovat podmíněně (2.10) a zůstanou i staré konstruktory – podivné chování PHP 4, kdy se metoda rodiče stala konstruktorem potomka, pokud měla stejné jméno, už není ani v PHP 5 (2.12).
  • U funkcí se nadále nebude rozlišovat velikost písmen, ale použití nesprávné velikosti pravděpodobně vyvolá E_STRICT (2.13).
  • Zápis do nedeklarované vlastnosti objektu nadále nevyvolá žádnou chybu (5.7) a zápis prvku do neinicializovaného pole zmíněn není, zůstane tedy spolu s bezpečnostními riziky (zmírněnými zakázáním register_globals) a těžko odhalitelnými chybami (posílenými definitivním nerozdělením operátorů pro přístup ke znakům řetězce a prvkům pole) bez jakéhokoliv varování.
  • Zahájení PHP bloku nadále bude možné pomocí krátkého <?, syntaxe <% naopak bude spolu s direktivou asp_tags odstraněna, <?php= přidáno nebude a blok bude možné ukončit pouze značkou odpovídající té, kterou byl zahájen (6.7). Z toho mi vyplývá, že syntaxe <script language="php"> zůstane zachována, přestože to není explicitně uvedeno.

Přidané novinky

Do jazyka přibudou i některé často diskutované novinky:

  • Vznikne typ int64, typ int zůstane platformově závislý (4.1), ale jestli se na tento typ bude převádět i při překročení velikosti čísla, zatím nevím.
  • Příkaz goto, o kterém se také vášnivě debatovalo, se do jazyka dostane, ale vzhledem k zásadním omezením (nebude možné skákat dovnitř bloků kódu a bude možné skákat pouze směrem vpřed) se pro něj použije syntaxe break label (4.2). Myslím, že to je vhodný kompromis použitelný pro ošetření chyb a těžko zneužitelný k používání ve stylu Basicu.
  • vášnivě probírané konstrukce ifsetor ještě definitivní rozhodnutí nepadlo, jisté je zatím pouze to, že u ternárního operátoru bude možné vynechat prostřední část (4.3).
  • V konstrukci foreach bude možné místo hodnoty používat funkci list (4.4). Párkrát by se mi tato konstrukce bývala hodila, dokonce čas od času zkouším, jestli v jazyce náhodou už není, vzhledem k jednořádkové náhradě to ale samozřejmě není nic zásadního.
  • Uvnitř operátoru [] bude možné používat složitější výrazy stejně jako u funkcí substr a array_slice (4.5). U řetězců proti tomu nic nemám, ale už se „těším“ na zmatky, které vyplynou z toho, že [] u pole bude moci vrátit kromě jednoho prvku také pole obsahující jeho část.
  • Za zásadní omyl považuji změnu výchozí hodnoty parametru funkce microtime (4.10). Připomínám, že před PHP 5 se tato funkce volala bez parametru a vracela řetězec. V PHP 5 byl přidán nepovinný parametr zajišťující, že funkce vrátí desetinné číslo s výchozí hodnotou způsobující původní chování. V PHP 6 se má výchozí hodnota tohoto parametru změnit tak, aby funkce bez parametru vracela desetinné číslo. Vývojáři to obhajují tím, že nejčastější použití funkce vracející řetězec ho stejně převádí na číslo a tento kód zůstane funkční (s jednou E_NOTICE navíc). Co ale ostatní použití funkce? Co když chce někdo třeba jenom desetinnou část a volá funkci bez parametru? Jednoduchá odpověď – v PHP 6 kód bez jakékoliv výstrahy přestane fungovat. Navíc mi není úplně jasné, jaký přínos tato změna přinese – o něco hezčí budoucí kód za cenu znefunkčnění mnoha skriptů myslím nestojí.
  • Konstrukce self:: se vždy vztahuje ke třídě, ve které je použita. Problém to může být u potomků, kdy by se často hodilo, aby se vztahovala ke třídě, přes kterou jsme se k self v rodiči dostali. Z toho důvodu bude zavedena nová konstrukce static:: (nebo možná this::), která tuto funkčnost zajistí (5.4).
  • Jmenné prostory se do PHP nakonec pravděpodobně dostanou, ale jejich přesná podoba ještě bude dořešena (5.6).
  • Statické volání nestatické metody vyvolá místo E_STRICT rovnou E_ERROR (5.10).
  • Z projektu Hardened PHP se do PHP převezmou některé opravy. Asi nejvýznamnější změnou bude vznik nové direktivy allow_url_inclu­de, která bude ovlivňovat používání vzdálených souborů při vkládání PHP kódu (6.2). Pokud nicméně zůstane zachována možnost používat ostatní wrappery, bezpečnostní riziko se zmírní jen částečně.
  • Chyby produkované jednotlivými rozšířeními budou zrevidovány a ve většině případů nahrazeny za E_WARNING nebo novou chybu E_RECOVERABLE_ER­ROR. Z té bude možné se vzpamatovat v případě, že bude ošetřena (6.4).
  • Úroveň chyb E_STRICT se stane součástí konstanty E_ALL, ale výchozí nastavení zůstane E_ALL & ~E_NOTICE, takže chyby E_STRICT ve výchozím nastavení zobrazovány budou, ale E_NOTICE ne (6.6). Zvláštní.

Zamítnuté novinky

Další novinky se naopak do jazyka nedostanou:

bitcoin_skoleni

  • Nebude umožněn průchod polem bez přiřazování hodnot do proměnné (4.7).
  • Na své si nepřijdou ani příznivci pojmenovaných parametrů funkcí (4.8).
  • Pořadí parametrů jednotlivých funkcí bude nadále začátečníkům činit problémy (4.9). Vývojáři jsou sice toho názoru, že to je u interních funkcí v podstatě konzistentní, ale nevzali v úvahu funkce pro práci s regulárními výrazy, které mají pořadí parametrů obráceně. Kromě toho funkce str_replace také přijímá prohledávaný řetězec až jako třetí parametr a ne jako první, jak je to zvykem v databázích a jak to má i strpos. I tak jsem rád, že k žádné změně nedojde, přeházení parametrů by způsobilo nedozírné zmatky a to i v případě, že by bylo doprovázeno např. přejmenováním funkcí na  str_*.
  • Při použití objektu v kontextu řetězce se volá metoda __toString. Pro použití v kontextu jiných primitivních typů nové magické metody nevzniknou a nadále se vždy bude volat tato (5.5).
  • Type-hinting je nyní možné používat u parametrů, nově bude zaveden i u návratových hodnot funkcí, naopak nebude zaveden u vlastností. Syntaxe bude ještě zvolena, osobně se mi nejvíc líbí function &ObjectName funcname() (5.8). Napovídání primitivních typů zmíněno není, takže v jazyce ani nadále s největší pravděpodobností nebude.
  • Nevznikne ani delegování metod rozhraní (5.12).
  • Interní PHP funkce ani nadále nebudou vyvolávat výjimky, protože překlad jednotlivých úrovní chyb lze na výjimky snadno zajistit již od jejich uvedení (6.5).

Závěr

Většinu změn je určitě možné hodnotit pozitivně. Unicode je nesporným přínosem, byť bude nutné chování jednotlivých kódování stejně jako u databází nejprve pečlivě nastudovat. Pozitivně lze hodnotit i odstranění konfiguračních direktiv, které ve většině případů hlavně u začínajících programátorů způsobovaly víc zmatku než užitku. Některé změny mi ale připadají poněkud samoúčelné ve snaze jazyk vyčistit, ovšem za cenu pomalého a bolestného přechodu. Je s podivem, že při pohledu na pomalý přechod na PHP 5 (způsobený ale hlavně důležitou změnou objektového modelu) se vývojáři chtějí pouštět do takových kousků jako je zbytečná změna výchozí hodnoty parametru u podružné funkce nebo odstranění čtyři roky doporučované syntaxe na úkor té, která byla označena jako zastaralá. Snaha o vyčištění jazyka se tak podle mého názoru ubírá ne zcela správným směrem – řada programátorů by spíše uvítala upozornění na potenciálně nebezpečné chování (jako je přiřazování prvků do neinicializovaného pole nebo do nedeklarovaných vlastností) nebo větší jednoznačnost jazyka (rozlišením operátorů pro přístup ke znakům řetězce a prvkům pole), zkrátka jeho lepší předvídatelnost. Místo toho ale např. dojde k tomu, že spolu se sjednocením parsování parametrů funkcí (všimněte si, že v současných verzích např. wordwrap("abc", "b"); informaci o špatném typu parametrů vypíše, ale substr("abc", "b"); ne) bude chybová hláška o nepřevoditelnosti na správný typ potlačena.

Cesta do vydání PHP 6 je nicméně ještě dlouhá a za tu dobu se ještě může leccos změnit.

Jaká syntaxe je nejlepší?

Autor článku

Autor se živí programováním v PHP, podílí se na jeho oficiální dokumentaci, vyučuje ho na MFF UK a vede odborná školení. Poznámky si zapisuje na weblog PHP triky.