Na navigaci | Klávesové zkratky

Jak probíhá shutdown v PHP a volání destruktorů?

Ukončení požadavku v PHP se skládá z těchto kroků prováděných v uvedeném pořadí:

  1. Volání všech funkcí registrovaných pomocí register_shutdown_function()
  2. Volání všech metod __destruct()
  3. Vyprázdnění všech output bufferů
  4. Ukončení všech rozšíření PHP (např. sessions)
  5. Vypnutí výstupní vrstvy (odeslání HTTP hlaviček, vyčištění output handlerů atd.)

Zaměříme se podrobněji na krok č. 2, tedy volání destruktorů. Samozřejmě už v prvním kroku, tedy při volání registrovaných shutdown funkcí, může dojít k destrukci objektů, např. pokud některá z funkcí držela poslední referenci na nějaký objekt nebo pokud byla samotná shutdown funkce objektem.

Volání destruktorů probíhá takto:

  1. PHP se nejprve pokusí zrušit objekty v globální tabulce symbolů.
  2. Poté volá destruktory všech zbývajících objektů.
  3. Pokud je provádění zastaveno např. kvůli exit(), zbývající destruktory se nevolají.

ad 1) PHP projde globální tabulku symbolů pozpátku, tj. začne od proměnné, která byla vytvořena jako poslední, a postupuje k proměnné, která byla vytvořena jako první. Při procházení zruší všechny objekty s refcount=1. Tato iterace se provádí, dokud takové objekty existují.

V podstatě se tedy dělá to, že a) odstraní všechny nepoužívané objekty v globální tabulce symbolů b) pokud se objeví nové nepoužívané objekty, odstraní je také c) a tak dále. Tento způsob destrukce se používá proto, aby objekty mohly být závislé na jiných objektech v destruktoru. Obvykle to funguje dobře, pokud objekty v globálním oboru nemají komplikované (např. kruhové) vzájemné vazby.

Destrukce globální tabulky symbolů se výrazně liší od destrukce ostatních tabulek symbolů, viz dále. Pro globální tabulku symbolů tedy PHP používá chytřejší algoritmus, který se snaží respektovat závislosti objektů.

ad 2) Ostatní objekty se prochází v pořadí podle jejich vytvoření a zavolá se jejich destruktor. Ano, PHP pouze zavolá __destruct, ale ve skutečnosti objekt nezruší (a dokonce ani nezmění jeho refcount). Pokud se tedy na objekt budou odkazovat jiné objekty, bude stále k dispozici (i když destruktor již byl zavolán). V jistém smyslu budou používat jakýsi „napůl zničený“ objekt.

ad 3) V případě, že je provádění zastaveno během volání destruktorů např. kvůli exit(), zbývající destruktory se nevolají. Místo toho PHP označí objekty za již destruované. Důležitý důsledek je, že volání destruktorů není jisté. Případy, kdy se tak stane, jsou spíše vzácné, ale stát se to může.

Zdroj https://stackoverflow.com/…ucted-in-php

před 3 lety v rubrice PHP | blog píše David Grudl | nahoru

Mohlo by vás zajímat

Napište komentář

Text komentáře
Kontakt

(kvůli gravataru)



*kurzíva* **tučné** "odkaz":http://example.com /--php phpkod(); \--

phpFashion © 2004, 2024 David Grudl | o blogu

Ukázky zdrojových kódů smíte používat s uvedením autora a URL tohoto webu bez dalších omezení.