Wie man die Geschwindigkeit des PHP-Skripts erkennt. PHP-Skript-Ausführungszeit

Unabhängig davon, wie viel wir PHP verwenden, werden immer noch einige Funktionen angezeigt, von denen wir noch nicht einmal gehört haben. Einige davon wären für uns sehr nützlich. Ich habe eine kleine Liste von nützlichen Funktionen erstellt, die jedem PHP-Programmierer zur Verfügung stehen sollten.

1. Erstellen von Funktionen mit einer variablen Anzahl von Argumenten

Höchstwahrscheinlich wissen Sie bereits, dass PHP es erlaubt, Funktionen mit optionalen Argumenten zu erstellen. Nun werde ich eine Funktion zeigen, bei der die Anzahl der Argumente von Fall zu Fall variieren kann.

Aber zunächst wollen wir uns daran erinnern, wie wir Funktionen auf die übliche Weise erstellen:

  // Funktion mit zwei optionalen Parametern function foo ($ arg1 = "", $ arg2 = "") (Echo "arg1: $ arg1 \\ n"; echo "arg2: $ arg2 \\ n";) foo ("hallo", "Welt"); / * wird ausgegeben: arg1: hallo arg2: world * / foo (); / * gibt aus: arg1: arg2: * /

Schauen wir uns nun an, wie Sie eine Funktion mit einer unbegrenzten Anzahl von Argumenten schreiben können. Verwenden Sie dazu die Methode func_get_args ():

  // Keine Argumente angeben function foo () (// gibt ein Array der übergebenen Argumente zurück $ args = func_get_args (); foreach ($ args als $ k =\u003e $ v) (Echo "arg". ($ k + 1). " : $ v \\ n ";)) foo (); / * gibt nichts aus * / foo ("hallo"); / * wird arg1 drucken: hallo * / foo ("hallo", "world", "again"); / * druckt arg1: hallo arg2: world arg3: wieder * /

2. Suchen Sie mit Glob () nach Dateien

Oft sprechen die Funktionsnamen für sich. Dies kann nicht über die Funktion glob () gesagt werden.

Ohne auf Details einzugehen, ähnelt seine Funktionalität der scandir () -Methode. Sie können die gewünschte Datei anhand eines Musters finden:

  // Finde alle php-Dateien $ files = glob ("*. php"); print_r ($ files); / * wird ausgegeben: Array (=\u003e phptest.php =\u003e pi.php =\u003e post_output.php =\u003e test.php) * /

Um Dateien verschiedener Typen zu finden, schreiben Sie Folgendes:

  // Finde alle php- und txt-Dateien $ files = glob ("*. (php, txt)", GLOB_BRACE); print_r ($ files); / * output: Array (=\u003e phptest.php =\u003e pi.php =\u003e post_output.php =\u003e test.php =\u003e log.txt =\u003e test.txt) * /

Sie können den Pfad auch in der Vorlage angeben:

  $ files = glob ("../ images / a * .jpg"); print_r ($ files); / * output: Array (=\u003e ../images/apple.jpg =\u003e ../images/art.jpg) * /

Um den vollständigen Pfad zum Dokument zu erhalten, verwenden Sie die Methode realpath ():

$ files = glob ("../ images / a * .jpg"); // Wende die Funktion "realpath" auf jedes Element des Arrays an $ files = array_map ("realpath", $ files); print_r ($ files); / * zeigt an: Array (=\u003e C: \\ wamp \\ www \\ images \\ apple.jpg =\u003e C: \\ wamp \\ www \\ images \\ art.jpg) * /

3. Informationen zum verwendeten Speicher

Wenn Sie den Speicherplatz nachverfolgen, der durch die Arbeit Ihrer Skripts verbraucht wird, werden Sie sie wahrscheinlich öfter optimieren.

In PHP gibt es ein leistungsfähiges Werkzeug zur Speicherüberwachung. In verschiedenen Teilen des Skripts kann das Laden unterschiedlich sein. Um den Wert des momentan verwendeten Speichers abzurufen, müssen Sie die memory_get_usage () -Methode verwenden. Zur Festlegung der maximal verwendeten Speichermenge memory_get_peak_usage ()

Echo "Initial:" .memory_get_usage (). "Bytes \\ n"; / * Initial: 361400 Byte * / // geben eine kleine Last für ($ i = 0; $ i< 100000; $i++) { $array = md5($i); } // и ещё for ($i = 0; $i < 100000; $i++) { unset($array[$i]); } echo "Final: ".memory_get_usage()." bytes \n"; /* Final: 885912 bytes */ echo "Peak: ".memory_get_peak_usage()." bytes \n"; /* Peak: 13687072 bytes */

4. Prozessorinformationen

Verwenden Sie dazu die getrusage () -Methode. Beachten Sie jedoch, dass diese Funktion unter Windows nicht funktioniert.

Print_r (getrusage ()); / * druckt Array (=\u003e 0 =\u003e 0 =\u003e 2 =\u003e 3 =\u003e 12692 =\u003e 764 =\u003e 3864 =\u003e 94 =\u003e 0 =\u003e 1 =\u003e 67 =\u003e 4 =\u003e 0 =\u003e 0 =\u003e 0 =\u003e 6269 =\u003e 0) * /

Das oben umrissene Bild wird denjenigen klar sein, die Erfahrung in der Systemadministration haben. Für alle anderen bieten wir Dekodierung an:

  • ru_oublock: Die Anzahl der Blockschreibvorgänge
  • ru_inblock: Die Anzahl der Blockleseoperationen
  • ru_msgsnd: Anzahl der gesendeten Nachrichten
  • ru_msgrcv: Anzahl der empfangenen Nachrichten
  • ru_maxrss: Die maximale Größe einer nicht-paggierten Gruppe
  • ru_ixrss: Gesamter gemeinsam genutzter Speicher
  • ru_idrss: Gesamtmenge der nicht gemeinsam genutzten Daten
  • ru_minflt: Die Anzahl der verwendeten Speicherseiten
  • ru_majflt: Anzahl der fehlenden Seiten
  • ru_nsignals: die Anzahl der empfangenen Signale
  • ru_nvcsw: Anzahl der Kontextwechsel nach Prozess
  • ru_nivcsw: Die Anzahl der erzwungenen Kontextwechsel
  • ru_nswap: Die Anzahl der Festplattenzugriffe beim Paging
  • ru_utime.tv_usec: Zeit im Benutzermodus (Mikrosekunden)
  • ru_utime.tv_sec: Benutzermodus (Sekunden)
  • ru_stime.tv_usec: Zeit im privilegierten Modus (Mikrosekunden)
  • ru_stime.tv_sec: Zeit im privilegierten Modus (Sekunden)

Um herauszufinden, welche Ressourcen Ihr Prozessor das Skript verwendet, benötigen Sie den Wert Benutzerzeit (Zeit im Benutzermodus) und Systemzeit (Zeit im privilegierten Modus). Sie können das Ergebnis in Sekunden und Mikrosekunden erhalten. Um die Gesamtzahl der Sekunden in eine Dezimalzahl umzuwandeln, müssen Sie den Wert in Mikrosekunden durch 1 Million teilen und zum zweiten Wert addieren.

Irgendwie verwirrt. Hier ist ein Beispiel:

  // Pause 3 Sekunden schlafen (3); $ data = getrusage (); echo "Benutzerzeit:". ($ data ["de_utime.tv_sec"] + $ data ["de_utime.tv_usec"] / 1.000.000); Echo "Systemzeit:". ($ data ["ru_stime.tv_sec"] + $ data ["ru_stime.tv_usec"] / 1.000.000); / * zeigt Benutzerzeit: 0.011552 Systemzeit: 0 * /

Obwohl die Ausführung des Skripts etwa 3 Sekunden dauerte, war der Prozessor nicht stark ausgelastet. Tatsache ist, dass das Skript beim Aufruf (sleep) praktisch keine Prozessorressourcen verbraucht. Im Allgemeinen gibt es viele Aufgaben, die viel Zeit in Anspruch nehmen, jedoch keinen Prozessor verwenden. Zum Beispiel: Warten auf Vorgänge, die der Festplatte zugeordnet sind. Daher verwenden Sie in Ihren Skripten nicht immer CPU-Zeit.

Hier ist ein anderes Beispiel:

  // 10 Millionen Mal laufen für ($ i = 0; $ i<10000000;$i++) { } $data = getrusage(); echo "User time: ". ($data["ru_utime.tv_sec"] + $data["ru_utime.tv_usec"] / 1000000); echo "System time: ". ($data["ru_stime.tv_sec"] + $data["ru_stime.tv_usec"] / 1000000); /* выводит User time: 1.424592 System time: 0.004204 */

Das Skript benötigte 1,4 Sekunden CPU-Zeit. In diesem Fall ist die Zeit für Systemaufrufe im Allgemeinen gering.

Die Betriebszeit im privilegierten Modus (System Time) ist die Zeit, die der Prozessor für die Ausführung von Systemanforderungen an den Kernel im Auftrag des Programms aufbringt. Beispiel:

  $ start = microtime (true); // Microtime alle 3 Sekunden aufrufen, während (Microtime (true) - $ start)< 3) { } $data = getrusage(); echo "User time: ". ($data["ru_utime.tv_sec"] + $data["ru_utime.tv_usec"] / 1000000); echo "System time: ". ($data["ru_stime.tv_sec"] + $data["ru_stime.tv_usec"] / 1000000); /* выводит User time: 1.088171 System time: 1.675315 */

Jetzt wurde die Systemzeit viel mehr aufgewendet als im vorherigen Beispiel. Alles dank der Methode microtime (), die Systemressourcen verwendet.

Es ist jedoch zu beachten, dass die angezeigte Zeit möglicherweise nicht genau ist, weil Zu diesem Zeitpunkt werden CPU-Ressourcen von anderen Programmen verwendet, was zu einem kleinen Fehler führen kann.

5. Magiekonstanten

Es gibt viele magische Konstanten in PHP, wie z. B. die aktuelle Zeilennummer (__LINE__), den Dateipfad (__FILE__), den Verzeichnispfad (__DIR__), den Funktionsnamen (__FUNCTION__), den Klassennamen (__CLASS__), den Methodennamen (__METHOD__) und den Namensraum (__NAMESPACE__).

Wir werden sie alle nicht berücksichtigen. Lass uns nur ein paar sehen:

// Dieses Skript hängt vom aktuellen Speicherort der Datei ab und // kann Probleme verursachen, wenn es aus verschiedenen Verzeichnissen verwendet wird. requir_once ("config / database.php"); // Dieses Skript verursacht keine Probleme. required_once (dirname (__ FILE__). "/config/database.php");

Verwenden Sie __LINE__ zum Debuggen von Skripts:

  // code // ... my_debug ("einige debug-nachricht", __LINE__); / * gibt Zeile 4 aus: einige Debug-Nachricht * / // anderer Code // ... my_debug ("andere Debug-Nachricht", __LINE__); / * gibt Zeile 11 aus: eine andere Debug-Nachricht * / function my_debug ($ msg, $ line) (echo "Line $ line: $ msg \\ n";)

6. Generieren von eindeutigen IDs

Es kann vorkommen, dass Sie eine eindeutige Zeichenfolge generieren müssen. Ich habe oft gesehen, dass die Funktion md5 () verwendet wird, um dieses Problem zu lösen:

  // ein zufälliges String-Echo erzeugen md5 (time (). mt_rand (1.1000000));

In der Tat gibt es zu diesem Zweck in PHP eine spezielle Funktion uniqid ().

  // einen zufälligen String erzeugen echo uniqid (); / * druckt 4bd67c947233e * / // noch einmal echo uniqid (); / * gibt 4bd67c9472340 aus * /

Mit dem bloßen Auge können Sie sehen, dass die ersten Zeichen leicht ähnlich ausgedrückt sind ... Dies liegt daran, dass diese Methode Serverzeit verwendet, um Zeichen zu generieren. Es ist sogar nützlich, weil Alle generierten Werte werden in alphabetischer Reihenfolge abgerufen, sodass sie schnell sortiert werden können.

Um die Wahrscheinlichkeit eines Duplikats zu verringern, können Sie ein Präfix hinzufügen oder den zweiten Parameter verwenden (erhöhen Sie die Anzahl der Zeichen):

  // mit dem Präfix echo uniqid ("foo_"); / * druckt foo_4bd67d6cd8b8f * / // mit dem zweiten Parameter echo uniqid ("", true); / * gibt 4bd67d6cd8b926.12135106 aus * / // beide echo uniqid ("bar _", true); / * druckt bar_4bd67da367b650.43684647 * /

Diese Methode generiert Zeichenfolgen, die kleiner als md5 sind, sodass Sie Platz sparen können.

7. Serialisierung

Haben Sie schon einmal komplexe Daten in einer Datenbank oder in einer Datei gespeichert? Um ein Objekt in PHP in einen String zu konvertieren, wird eine spezielle Funktion bereitgestellt.

Im Allgemeinen sind diese Methoden 2: serialize () und unserialize ()

  // komplexes Array $ myvar = Array ("Hallo", 42, Array (1, "Zwei"), "Apfel"); // in String konvertieren $ string = serialize ($ myvar); echo $ string; / * druckt a: 4: (i: 0; s: 5: "hallo"; i: 1; i: 42; i: 2; a: 2: (i: 0; i: 1; i: 1; s : 3: "two";) i: 3; s: 5: "apple";) * / // wir erhalten den Ausgangswert $ newvar = unserialize ($ string); print_r ($ newvar); / * zeigt Array an (=\u003e Hallo =\u003e 42 =\u003e Array (=\u003e 1 =\u003e zwei) =\u003e Apfel) * /

So funktionieren diese Funktionen. Aufgrund der boomenden Popularität von JSON wurden jedoch 2 PHP-Methoden json_encode () und json_decode () zu PHP 5.2 hinzugefügt. Ihre Arbeit ist ähnlich zu serialize ():

  // komplexes Array $ myvar = Array ("Hallo", 42, Array (1, "Zwei"), "Apfel"); // in String konvertieren $ string = json_encode ($ myvar); echo $ string; / * druckt ["Hallo", 42 ,, "Apfel"] * / // stellt den ursprünglichen Wert wieder her $ newvar = json_decode ($ string); print_r ($ newvar); / * druckt Array (=\u003e Hallo =\u003e 42 =\u003e Array (=\u003e 1 =\u003e zwei) =\u003e Apfel) * /

Diese Option ist kompakter und mit anderen Sprachen wie JavaScript kompatibel. Bei sehr gehäuften Objekten kann es jedoch zu Datenverlust kommen.

8. Linien komprimieren

Wenn wir über Komprimierung sprechen, fallen mir sofort ZIP-Archivdateien ein. PHP bietet die Möglichkeit, lange Zeilen ohne Dateien zu komprimieren.

Im folgenden Beispiel werden wir die Funktionsweise der Funktionen gzcompress () und gzuncompress () demonstrieren:

  $ string = "Lorem ipsum dolor sitzt amet, consectetur adipiscing elit. Nab ut elite mi ultricies adipiscing. Nulla facilisi. Präsentieren Sie Pulvinar, Vestibulum sapien vel feugiat, Nulla dui pretium orci, nicht ultrounds elecetete et eetetetetetetet. Adipiscing elit Aliquam pretium ullacorper urna quis iaculis, Etiam ac massa sed turpis tempor luctus, curabitur sed nibh eu elit mollis congue. ornare in mollis, ornare in mollis, ornare in mollis, ornare in mollis, motten innos mintis, in leto cone mollis. . "; $ komprimiert = gzcompress ($ string); Echo "Originalgröße:". strlen ($ string). "\\ n"; / * zeigt Originalgröße: 800 * / Echo "Komprimierte Größe:". strlen ($ komprimiert). "\\ n"; / * print Komprimierte Größe: 418 * / // return $ original = gzuncompress ($ komprimiert);

Wir können die Textmenge um 50% reduzieren. Zu demselben Zweck können Sie die Methoden gzencode () und gzdecode () verwenden, die einen anderen Kompressionsalgorithmus verwenden.

9. Führen Sie vor dem Abschluss aus

In PHP gibt es eine register_shutdown_function () - Funktion, mit der Sie vor dem Beenden des Skripts Code ausführen können.

Angenommen, Sie möchten einige Informationen herausfinden ... Skriptlaufzeit:

// Holen Sie sich die Startzeit $ start_time = microtime (true); // einige Operationen // ... // leiten das Laufzeitecho "Ausführung nahm:" ab. (microtime (true) - $ start_time). "Sekunden".

Auf den ersten Blick mag dies eine triviale Aufgabe sein. Zu diesem Zweck können Sie den Code am Ende der Datei einfügen. Wenn jedoch zuvor die exit () - Funktion irgendwo funktioniert, wird dieser Code niemals funktionieren. Es funktioniert auch nicht, wenn auf der Seite ein Fehler auftritt oder der Benutzer das Laden der Seite unterbricht (durch Klicken auf die entsprechende Schaltfläche in Ihrem Browser).

Bei Verwendung der register_shutdown_function () -Methode wird der Code trotzdem ausgeführt:

  $ start_time = microtime (true); register_shutdown_function ("my_shutdown"); Funktion my_shutdown () (global $ start_time; Echo "Ausführung dauerte:". (microtime (true) - $ start_time). "Sekunden".);

Fazit

PHP ist ein ganzer Planet, der uns immer wieder mit seinem Inhalt überrascht. Was denkst du über diese Funktionen?

10. Februar 2012 13 Rubrik :,

Manchmal müssen Sie genau auf die Ausführungsgeschwindigkeit eines Skripts (oder eines Teils des Skripts) achten, nicht auf Ihre kurzen, geschulten Augen. Das ist der Moment, an dem PHP-Funktionen zur Messung der Download-Geschwindigkeit zur Rettung kommen. Sie haben sie wahrscheinlich benutzt, und im Allgemeinen wissen Sie, wie es geht. Nur für den Fall, für diejenigen, die nicht wissen, wie es geht, sowie für den Abschnitt "Wichtige Kleinigkeiten", gebe ich den einfachsten Code, der dieses Problem löst.

$ start = microtime (true);
// Skriptkörper
echo "Skriptausführungszeit:" (microtime (true) - $ start). "sec.";

Alles ist verrückt. In der ersten Zeile erstellen wir eine Variable mit einer Startzeit. Es wird durch die Funktion erreicht mikrotime  Mit übertragenem true - Damit können Sie die Anzahl der Sekunden mit einer großen Anzahl von Dezimalstellen ermitteln. Zeit übrigens im Unix-Format.

Als nächstes kommt der gesamte Skriptcode. Danach ziehen wir in der dritten Zeile den Start des Skripts und der Voila von der aktuellen Uhrzeit ab - Sie haben die Zeit, das PHP-Skript mit der Genauigkeit des Dezimalpunkts auszuführen.


Wie lange funktionieren "schwere" Skripts weiterhin, wenn nicht auf das Ende ihrer Arbeit gewartet wird, um den Browser zu schließen? Und werden sie ihre Arbeit fortsetzen? Wie die Beobachtungen gezeigt haben, leben sie weiter und versuchen, die ihnen zugewiesene Arbeit zu erledigen. Viele, um diese Art von "dunklem" Leben von Skripten zu kontrollieren, greifen auf Typanweisungen zurück

ignore_user_abort (boolescher Modus)

Wenn diese Anweisung mit aufgerufen wird falsch Parameter entspricht es seiner Abwesenheit. Normalerweise wird es mit dem Parameter angegeben wahr - ignore_user_abort (true). Dies ist in Fällen erforderlich, in denen Sie das Skript fortsetzen müssen, auch wenn der Browser die Verbindung getrennt hat. Im Allgemeinen kann PHP den Verbindungsstatus verfolgen. Ich war an der Situation mit der Fortsetzung des Skripts interessiert, auch nachdem das Browserfenster geschlossen wurde. Es ist sehr einfach zu überprüfen: Schreiben Sie ein Skript, das für eine Weile ausgeführt wird, starten Sie es und schließen Sie das Browserfenster, bevor Sie warten, bis das Skript beendet ist. Vergessen Sie nicht, eine Abschaltmarkierung im Skript hinzuzufügen, beispielsweise eine Datei zu erstellen. So können Sie die Leistung Ihres Skripts nachverfolgen. Nach Abschluss der Sitzung des Agenten (Browsers) sollte das Skript generell beendet werden. Wie Sie jedoch sehen können, ist dies nicht ganz so: Es versucht immer noch, länger zu leben. In diesem Fall ist es sinnvoll, ihn in die Hintergrundausführung (cron) zu übertragen. Es war jedoch immer noch interessant, diese Funktion zu analysieren. Die Anweisung wird verwendet, um den Verbindungsstatus zu verfolgen. verbindungsstatus (). Für weitere Manipulationen wurden die Hüllen geschrieben:

// Rückgabecode des Verbindungsstatus
function getConnectStatus () (
  return Verbindungsstatus ();
}

// Rückgabetyp des Verbindungsstatus anhand des Codes
funktion getConnectStatusByCode ($ connectionStatus) (
  Schalter ($ connectionStatus) (
  case CONNECTION_NORMAL:
  $ status = "Normal";
  brechen;
  case CONNECTION_ABORTED:
  $ status = "Benutzerabbruch";
  brechen;
  case CONNECTION_TIMEOUT:

  $ status = "Maximale Ausführungszeit überschritten";
  brechen;
  case (CONNECTION_ABORTED & CONNECTION_TIMEOUT):
  $ status = "Abgebrochen und abgelaufen";
  brechen;
  Standard:
  $ status = "unbekannt";
  brechen;
}
  $ status zurückgeben;
}



}

Jetzt können Sie eine Funktion schreiben, die jede lange Arbeit simuliert

// Nachahmung eines langen Skripts
funktion scriptImitation () (

  $ start = time ();

  $ limitIteration = 1.000.000;
  for ($ i = 0; checkConnectionStatus () && ($ i< $limitIteration); $i++) {
  // etwas lange arbeit ...
}

  $ end = time ();
  $ runTime = $ end - $ start;

If ($ i === $ limitIteration ||! CheckConnectionStatus ()) (
  $ connectStatus = getConnectStatusByCode (getConnectStatus ());
  $ scriptImitationLog = "Verbindungsstatus: $ connectStatus";
  $ scriptImitationLog. = ";";
  $ scriptImitationLog. = "Iteration: $ i";
  $ scriptImitationLog. = ";";
  $ scriptImitationLog. = "Laufzeit: $ runTime second";

File_put_contents ("scriptImitationLog.txt", $ scriptImitationLog);
}

Eigentlich beginnen wir regelmäßig damit, die Arbeit an unserem Skript einzustellen. Egal wie schnell ich das Agentenfenster schließen wollte, das Skript funktionierte immer noch erfolgreich und an der Ausgabe wurde ein Protokoll erstellt. Vergiss das nicht max_execution_time, das Skript wird definitiv nicht länger als diese Zeit leben. In unserem Fall wurde es erhöht. Schauen wir uns das Protokoll an:

Verbindungsstatus: Normal; Iteration: 1.000.000; Laufzeit: 5 Sekunden

Wie Sie sehen, ist die Verbindung normal, der Zyklus hat bis zum Ende gearbeitet. Also, was ist der Deal? In diesem Artikel über stackoverflow  Ich habe diese Lösung hier gefunden - http://stackoverflow.com/questions/2389035/php-connection-status. Und es wurde mit dem Ausgabepuffer verbunden: In regelmäßigen Abständen wird ein kleiner Teil der Daten (z. B. ein leeres Zeichen) in den Ausgabepuffer des Skripts geschrieben und dann zurückgesetzt (normalerweise bedeutet PHP, dass der gesamte Inhalt gesendet und anschließend gelöscht wird). Zu diesem Zweck wird vorgeschlagen, die gemeinsame Nutzung von Funktionen zu nutzen. ob_flush  und spülung. Und da zum Zurücksetzen eine Verbindung impliziert ist (schließlich ist der Puffer so ausgebildet, dass er in Richtung Browser - Initiator gesendet wird), wird der Status beim nächsten Zurücksetzen, wenn keine normale Verbindung besteht, in einen anderen Status ( Benutzer abgebrochen). Und wenn das Skript keine Anweisungen enthält oder im Formular angegeben ist

ignore_user_abort (false);

Wenn sich der normale Verbindungsstatus ändert, wird das Skript sofort angehalten, wenn eine Anweisung vorliegt

ignore_user_abort (true);

Selbst wenn sich der Verbindungsstatus ändert, wird das Skript bis zum Ende weiter ausgeführt. In diesem Fall kann der Verbindungsstatus jedoch überwacht werden. In diesem Sinne modifizieren wir eine der Umhüllungen geringfügig.

// den Verbindungsstatus überprüfen (true - normal, false - abnormal)
funktion checkConnectionStatus () (
  print "";
  ob_flush ();
  Flush ();
  return Verbindungsstatus () === 0;
}

Jetzt ist alles unter Kontrolle, und wenn wir unseren Browser schließen, wird das Skript angehalten oder ein anderes Verhalten kann organisiert werden.
  Zum Schluss werde ich die Ergebnisse einer weiteren Beobachtung geben. Wenn Sie die Laufzeit des Skripts in den Protokollen vergleichen, bevor Sie Änderungen vornehmen, und später im Wrapper - checkConnectionStatus,
  Daraus kann geschlossen werden, dass das Zurücksetzen des Ausgabepuffers sehr lange dauert. Die Zeit für eine Iteration im Testskript ohne Zurücksetzen des Puffers dauerte also durchschnittlich - 0,005 msmit Reset - 0,028 msd. h. eine durchschnittliche Pufferbereinigung dauerte 0,023 msdas in 4,6 mal die Zeit einer Iteration. Dies zeigt, dass das obige Verfahren zum Nachverfolgen der Lebensdauer von "schweren" Skripts die Hauptzeit erhöhen kann. Dieser Test wurde mit Firefox Version 29.0.1 durchgeführt. Alles Erfolg.

Verwirrt mich hier, einen Dämon in PHP zu schreiben. Ie ein Skript, das in einer bestimmten Anzahl von Stunden zu einer zufälligen Zeit (immer zufällig) mehrfach angegeben wird, um bestimmte Aktionen auszuführen, und all dies ohne Verwendung von cron "a.

Ich habe mich noch nie darum gekümmert, aber nachdem ich die Aufgabe gesetzt hatte, begann ich zu denken, dass es falsch war, das PHP-Skript vom Browser aufzurufen. Nun ja, die Aufgabe ist gesetzt und muss erledigt werden.

Der erste Gedanke ist, das Zeitlimit für die Skriptausführung zu deaktivieren. Verbotener Hoster

Der zweite Gedanke ist, die Ajax-Anfrage periodisch zu wiederholen (Ja, mindestens einmal pro Sekunde). - es ist unmöglich (die Anforderung des Kunden).

Es stellte sich heraus, dass der Browser nicht geöffnet sein sollte und cron nicht verwendet werden kann und das Skript unabhängig vom Benutzer auf unbestimmte Zeit funktionieren sollte. Natürlich sollte er das System zumindest versenden.

  1. Eine Packung Zigaretten, Nacht, Google, Docks, Bücher, Handbücher ....
  gehe zu 1 ...

Bei der Ausfahrt bekomme ich:
  Aufgabe_1:
  Implementieren Sie den Skriptausführungszeitgenerator basierend auf der angegebenen Anzahl von Malen und der Anzahl der Stunden. Behalte diese Zeiten irgendwo.

Aufgabe_2:
  Arbeit nach dem Schließen des Browsers

Aufgabe_3:
  Absturz nach Ablauf der Skriptzeit nicht mehr

Aufgabe_4:
  Führen Sie einige Aktionen zum richtigen Zeitpunkt aus.

Also ...
  Wir schreiben die Anfangsdaten in die Config:

Session_start (); // Die Sitzung starten $ num_starts = 120; // Anzahl der Skriptstarts innerhalb eines Zeitraums $ hours = 1; // Die Anzahl der Stunden, in denen Sie das Skript $ num_starts times ausführen müssen. $ time_sec = $ hours * 3600; // Die Anzahl der Sekunden in der Laufschleife $ time_to_start = array (); // Eigentlich ein Array mit Startzeiten ignore_user_abort (1); // Browserbruch ignorieren

Schreiben Sie als Nächstes eine Funktion, mit der Sie Startzeiten generieren können.
  Darin generieren wir eine Zufallszahl von 0 bis zur Anzahl Sekunden im ursprünglichen Intervall.
  / ****** * @desc Erzeugt das Intervall zwischen den Läufen. * / function add_time2start () (global $ time_sec, $ time_to_start; $ new_time = time () + rand (0, $ time_sec); if (! in_array ($ new_time, $ time_to_start))) (// Wenn keine solche Zeit im Array vorhanden ist - addiere $ time_to_start = $ new_time;) else (add_time2start (); // Wenn Sie diese Zeit bereits haben, generieren Sie sie erneut.))

  $ k = 1; if ($ _SESSION ["num_st"] == "" || $ _SESSION ["num_st"] [$ num_starts-1]< time()) { // проверка, что в сессию не записаны данные и что эти данные не устарели. do { add_time2start($k); $k++; } while ($k < = $num_starts); sort($time_to_start, SORT_NUMERIC); $_SESSION["num_st"] = $time_to_start; }

Jetzt müssen wir das Skript zum Laufen bringen, ohne auf die vom Server eingestellte maximale Ausführungszeit zu achten.
  Das Prinzip lautet:
  1) Bestimmen Sie die Startzeit des Skripts.
  2) Wir bestimmen die festgelegte Grenze für die Ausführungszeit.
  3) Wir starten den Zyklus, in dem wir die aktuelle Zeit zählen und die Gesamtzeit des Skripts berechnen, die aktuelle Zeit mit den Werten im Array der Startzeiten überprüfen und bei Übereinstimmung die angegebenen Aktionen ausführen (ich habe sie in der Datei exec.php). Um die Dateien auszuführen, verwenden Sie Sockets.
  4) Wiederholen Sie den Zyklus, bis die Skriptlaufzeit nahe dem maximal zulässigen Wert liegt. Ich habe eingestellt - bis die maximale Zeit 5 Sekunden beträgt.

Also ... betrachten wir die Anfangsdaten rechtzeitig:

  $ start_time = microtime (); // Finden Sie die Startzeit des Skripts heraus $ start_array = explode ("", $ start_time); // Sekunden und Millisekunden trennen $ start_time = $ start_array; // erhalte die Startzeit des Skripts $ max_exec = ini_get ("max_execution_time"); // Holen Sie sich die maximal mögliche Laufzeit des Skripts
  Eigentlich der Zyklus. Kommentare im Code.

Do ($ nowtime = time (); // aktuelle Uhrzeit //// Wenn sich die aktuelle Uhrzeit in einem Array mit Skriptausführungszeiten befindet ...... wenn (in_array ($ nowtime, $ _SESSION ["num_st"])))) // Mit dem Socket klammern wir uns an die Datei mit dem Hauptinhalt der Aktionen $ http = fsockopen ("test.ru", 80); /// zur gleichen Zeit übertragen wir ihr Sitzungsdaten und den Zeitpunkt, zu dem sie fputs auslösen sollen ($ http, "GET http: // test .ru / exec.php? ". session_name ()." = ". session_id ()." & nowtime = $ nowtime HTTP / 1.0 \\ r \\ n "); fputs ($ http," Host: test.ru \\ r \\ $ now_array = explodieren ("", $ now_time); $ now_time = $ now_array; // Sie Aus der aktuellen Zeit gelesen, die anfängliche anfängliche $ exec_time = $ now_time - $ start_time + $ exec_time; /// für einen zweiten Usleep bremsen (1000000); // Stoppen Sie das Skript im Hintergrund. Ich habe nicht an einen anderen Weg gedacht .txt ")) exit; // Überprüfung der Laufzeit. Wenn weniger als 5 Sekunden bis zum Ende des Skripts verbleiben, beenden Sie die Schleife. ) while ($ exec_time< ($max_exec - 5));

Nun, wenn die erlaubte Zeit zu Ende geht, beenden wir den Zyklus und führen dasselbe Skript sicher durch den anderen Prozess aus (in 5 Sekunden bleiben wir nur innerhalb)

// Führen Sie das gleiche Skript mit dem neuen Prozess aus und beenden Sie das aktuelle $ http = fsockopen ("test.ru", 80); fputs ($ http, "GET http://test.ru/index.php?" .session_name (). fputs ($ http, "Host: test.ru \\ r \\ n"); fputs ($ http, "\\ r \\ n"); fclose ($ http);

Als ich alles hinzufügte, war ich von einer nützlichen Anwendung verwirrt ... Sie können es als Dienst verwenden. Er kann etwas im Netzwerk überwachen und Sie beispielsweise per E-Mail benachrichtigen. Und brauche keine Cron.

Das Skript kann noch optimiert werden - es hat bei der Revision nicht funktioniert.
  Übrigens, davon konnte ich mich nicht losreißen - der Browser muss zunächst geöffnet werden, um das Skript starten zu können.

Grüße an euch, liebe Blogleser webcodius! Also sofort auf den Punkt. Zunächst werde ich den zweiten Teil der Frage beantworten: Warum könnte es notwendig sein? messen Sie die Skriptausführungszeit? Beim Debuggen von Webprojekten ist ein wichtiger Faktor, der berücksichtigt werden muss, die Ausführungszeit der Skripts. Dieser Parameter ist notwendig, um zu verstehen, wie schnell und effizient dieser oder jener Code funktioniert. Nachdem Sie die Zeit ermittelt haben, die der Server für die Ausführung des PHP-Skripts benötigt, können Sie abschließen, ob eine Codeoptimierung erforderlich ist oder nicht. Als nächstes überlegen Sie, wie es geht.

Um die Leistung von PHP-Skripten zu analysieren, gibt es verschiedene Erweiterungen und Bibliotheken wie XDebug, die Skripts debuggen und sie zur Laufzeit profilieren können. Um solche Erweiterungen verwenden zu können, müssen Sie sie jedoch erst installieren und konfigurieren. Um die Arbeit großer Projekte mit einer Solo-Architektur, einer großen Anzahl von Skripts und Millionen von Codezeilen zu optimieren, ist es natürlich besser, solche Erweiterungen zu verwenden. Wenn Sie jedoch 3-4 Skripts mit ein oder zweihundert Codezeilen optimieren müssen, können Sie PHP-Tools verwenden, um die Laufzeit von Skripts zu messen.

So bestimmen Sie die Skriptausführungszeit in PHP

Lernen Sie, professionelle Engines in PHP und MySQL zu erstellen

Diese Aufgabe wird mit Hilfe von Funktionen zum Arbeiten mit Datum und Uhrzeit, nämlich der integrierten Funktion microtime (), gelöst, die die Anzahl der Sekunden seit Mitternacht am 01.01.1970 zurückgibt. Durch zweimaliges Aufrufen dieser Funktion können wir die verstrichene Zeit zwischen Aufrufen berechnen:

Wenn Sie das Skript ausführen, sieht das Ergebnis etwa so aus:

Skriptausführungszeit: 0.00059400000000001

Kurz wie es funktioniert. Mit der Funktion microtime (true) speichern wir die Startzeit des Skripts in der Variablen $ start. Als nächstes folgt der Arbeitscode, der einige Aktionen ausführt. In diesem Beispiel wird einfach die Funktion usleep () aufgerufen, die das Skript für eine bestimmte Anzahl von Mikrosekunden verlangsamt. Dann erhalten wir die Endzeit des Skripts, speichern es in der Variablen $ end und berechnen die Ausführungszeit des Codes, indem $ start von $ end abgezogen wird. Als Ergebnis bekam das Laufzeitskript.

Jetzt wissen, wie man in definiert pHP-Skript-Ausführungszeitkönnen Sie mit der Optimierung verschiedener Codeblöcke beginnen. Viel Glück und bis bald in den nächsten Beiträgen!

Fortsetzung des Themas:
Smart TV

Analoges Fernsehen ist eine Schlüsselstufe in Wissenschaft, Fortschritt und Technologie. Durch frühere Entdeckungen konnte die Menschheit alle wichtigen Ereignisse wahrnehmen. Die Erfindung des Fernsehens ...