2014-05-06 3 views
8

Soweit ich weiß, erzeugt PHP für jeden Client, der mit dem Server verbunden ist, einen neuen Thread dafür. Aber ich frage mich, ob es wahr ist oder nicht, und wenn es wahr ist, wie lange bleibt dieser Thread am Leben? Behält dieser Thread alle statischen Variablen richtig bei? (wie eine DB-Verbindung)Wie behandelt der PHP-Kern Client-Verbindungen?

Wenn dieser Thread zerstört wird, ruft es alle Destruktoren auf?

+3

Siehe auch [diese Frage] (http://stackoverflow.com/questions/14183397/php-request-lifecycle) (nicht genau ein dupe zu schließen gegen) –

+1

Fragen Sie nach 'mod_php' oder' php' selbst ? – kojiro

Antwort

6

Es hängt alles davon ab, wie PHP mit dem Server eingerichtet wird. Ich bin mehr mit Apache/PHP-Combo vertraut (und nicht sagen, Nginx und FastCGI mit PHP-Konfiguration), so auf diesem Gebiet konzentriert:

  1. PHP in der Regel in Apache als DSO (Dynamic Shared-Objekt) integriert ist, Modul.

  2. Apache normalerweise unter Linux/Unix wird normalerweise als "vorgekipptes" Modell eingerichtet - dh wenn es gestartet wird, wird eine Reihe von Kind-Prozessen verzweigt (die genaue Anzahl kann über Apache-Anweisungen konfiguriert werden), und Sie sind in einem "Pool von Prozessen" bereit, Anfragen zu bearbeiten.

  3. Wenn eine Anfrage eingeht, wählt der Kernel-Scheduler einen Apache-Prozess aus dem Pool (falls verfügbar), und die Anfrage wird vom Kind behandelt.

  4. Wenn das Apache-Setup erkennt, dass ein PHP-Skript ausgeführt werden muss, übergibt es das PHP-DSO wie in (1) eingerichtet.

  5. Daher ist keine Verzweigung oder Threading auf Anfrage erforderlich, was effizient ist. Der gesamte Anfragekontext wird an die PHP-Ebene übergeben, die mit dem Kompilieren und Ausführen des PHP-Skripts beginnt.

    Hinweis: Der Kompilierungsschritt kann umgangen werden, wenn ein Opcode-Cache aktiviert ist - dh die erste Anfrage für ein PHP-Skript ist erfüllt und die zugehörigen Opcodes werden zwischengespeichert, um für nachfolgende Anfragen wiederverwendet zu werden). Da der Übersetzungsschritt teuer ist (Analyse des Skripts usw.), ist es für Produktionssysteme am besten, einen Opcode-Cache zu aktivieren.

  6. Wenn das PHP-Skript abgeschlossen ist, geht es in eine Bereinigungsroutine (integriert in das PHP-DSO) und es wird den pro-Request-Speicher bereinigen, schließen Sie alle Dateibeschreibungen einschließlich Db-Handles (basierend auf wie es ist geöffnet). Einige PHP-Methoden haben "persistente" Handles (z. B. öffnende db-Verbindungen, Datei-Handles), die über Anfragen hinweg gehalten werden können. Daher ist es wichtig, welche Funktion Sie zum Öffnen einer bestimmten Ressource verwenden (was die jeweilige Dokumentation hervorhebt). Standardmäßig werden die meisten Ressourcen nur während der Laufzeit einer PHP-Anfrage gehalten und nach Abschluss der PHP-Anfrage zerstört.

    In Bezug auf PHP-Objekt-Dktoren hängt alles davon ab, in welchem ​​Bereich das Objekt erstellt wird. Bei globalen Objekten werden ihre dtors nur am Ende des Anforderungszyklus aufgerufen, während einige von ihnen aufgerufen werden, wenn sie bei der Rückgabe einer Funktion den Gültigkeitsbereich verlassen.

    Daher erhalten Sie Speicher/Ressourcen-Management kostenlos. Sie können es über unset() - Aufrufe steuern, indem Sie sofort eine Freischaltung auslösen. Ab PHP 5.3 kann die Garbage Collection auch während der Request-Handling-Phase aktiviert werden - siehe hier: http://www.php.net/manual/en/features.gc.php

  7. Nun ist dieser Apache-Nachfolger (der das PHP-Script ausgeführt hat) wieder in den Pool der Prozesse, die bereit sind, zu verarbeiten die nächste Anforderung, wie in Schritt 3.

Was ich oben ist für einen Apache/PHP unter Linux/Unix-Umgebungen typisch beschrieben, aber ich denke, etwas ähnliches gilt für Microsoft zu Setups.

Auch mit Nginx und FastCGI + PHP denke ich, dass der gleiche Zyklus gilt - d. H. Dinge werden am Ende eines Anfragezyklus aufgeräumt, den das PHP + FastCGI-Modul behandelt. Auch hier wird, wenn nginx startet, ein Pool separater Prozesse gestartet, die vom FastCGI + PHP-Modul behandelt werden, und die Kommunikation zwischen nginx und FastCGI + PHP erfolgt in einem Unix-Socket.

Hoffe, das hilft.

+3

+1 Ausgezeichnete Antwort und ich möchte etwas über persistente Verbindungen erweitern. Bitte lesen Sie ** [this] (http://stackoverflow.com/questions/23432948/fully-understanding-pdo-attr-persistent/23480158#23480158) ** für weitere Details. – MonkeyZeus

5

Es ist nicht PHP, sondern Webserver, der Anfragen bearbeitet. PHP läuft nicht von selbst. Wenn die Webseite PHP-Code enthält, wird diese Anfrage durch das entsprechende PHP-SAPI-Modul an PHP delegiert. Es gibt Multi-Thread-, Multi-Prozess-Webserver und man kann sich sogar einen einzelnen Prozess-Webserver vorstellen, so dass es rein Webserver-abhängig ist, ob ein separater Thread oder Prozess für eine Anfrage erstellt wird.

In vielen Orten der PHP-Dokumentation Sie Zeilen wie diese auf umask() treffen können:

Vermeiden Sie mit dieser Funktion in Multithreaded Webservern. Es ist besser, ändern Sie die Dateiberechtigungen mit Chmod() nach dem Erstellen der Datei. Die Verwendung von umask() kann zu einem unerwarteten Verhalten von gleichzeitig ausgeführten Skripten und dem Webserver führen, da alle die gleiche Umask verwenden.

... wie lange bleibt dieser Thread am Leben? Werden in diesem Thread alle statischen Variablen ordnungsgemäß verwaltet? (wie eine DB-Verbindung)

Sie klingen wie eins mit C++ Hintergrund. Sie meinen wahrscheinlich globale Variablen in PHP. PHP hat eingebaute Unterstützung für Datenbankverbindungen und Sie sollten sich über solche Dinge keine Sorgen machen. Sie sind Implementierungsdetails. Die meisten SAPIs bieten persistente Datenbankverbindungen, aber dies ist nur für Ihre Neugier. Permanente Verbindungen werden pro Prozess erstellt, der Anforderungen verarbeitet. In diesem Fall werden sie eher durch einen Prozess als durch einen Thread verwaltet.

Wenn dieser Thread zerstört wird, ruft es alle Destruktoren auf?

In PHP werden Destruktoren aufgerufen, wenn das Skript die Ausführung beendet. Aus Sicht des PHP-Entwicklers spielt es keine Rolle, wo das Skript lebt.

+1

Sie sagen immer "Web-Server". Ich weiß, was Sie meinen, aber ich denke, "Anwendungsserver" ist hier genauer. [ref] (http://stackoverflow.com/a/936257/418413) – kojiro

+1

@kojiro Nun, das ist, was Webserver wurden, aber OP fragt nach HTTP-Anfragen, so denke ich, "Webserver" passt besser. So nennt PHP sie auch manuell. – doc