Ein On/Offliner Checker ist für viele Dinge praktisch. Zum Beispiel wenn unsere Lieblingsseite wieder mal nicht erreichbar ist und man sich fragt “Liegt es an mir, oder ist es ein Serverproblem?”. Dienste wie downforeveryoneorjustme.com helfen bei so etwas schnell und zuverlässig weiter. Ein einfaches Eingeben der URL verrät uns, ob die Seite für andere noch erreichbar ist.
Für ein Projekt brauchte ich eine geeignete Implementierung eines solchen Scripts. Zuallerst habe ich die passende Funktion gesucht, um mit PHP überhaupt die Antwortheader einer Anfrage auszulesen. Glückerlicherweise bot sich dafür direkt die Funktion get_header() an, welche die Daten in einem Array speichert. Übrigens soll dies die langsamste Variante sein, die Responseheader auszulesen, wie ein User nach 10.000.000 Testläufen auf php.net erzählt:
I found that this function is the slowest in obtaining the headers of a page probably because it uses a GET request rather then a HEAD request. Over 10,000,000 trials of obtaining the headers of a page from a server i found the following (results in seconds).
cURL: Mean: 0.584127946. Sigma: 0.050581736.
fsocketopen: Mean: 0.622114251. Sigma: 0.263170424.
get_headers: Mean: 0.90375551. Sigma: 0.273823419.
cURL was the fastest with fsocketopens being the second fastest. I noticed as well that fsocketopen had some outliers where as cURL did not.
Für meine Funktion ist dies jedoch ziemlich egal, da hier keine großartige Perfomance benötigt wird. Ich mache daher trotzdem mit get_header() weiter. Schauen wir uns zu allererst mal die empfangenen Daten im Array an:
Array ( [0] => HTTP/1.1 200 OK [1] => Date: Sat, 29 Aug 2011 12:28:13 GMT [2] => Server: Apache/1.3.27 (Unix) (Red-Hat/Linux) [3] => Last-Modified: Wed, 08 Jul 2011 23:11:55 GMT [4] => ETag: "3f80f-1b6-3e1cb03b" [5] => Accept-Ranges: bytes [6] => Content-Length: 438 [7] => Connection: close [8] => Content-Type: text/html )
Auf Position 0 (also quasi auf der ersten Position) wird uns direkt der Response Code 200 für “Erfolg” ausgegeben.
Wer sich mit den Response Codes nicht auskennt, für den habe ich hier eine kleine Übersicht:
1xx - Information - die Bearbeitung der Anfrage dauert noch an.
2xx - Erfolgreiche Information - die Bearbeitung der Anfrage kann durchgeführt werden.
3xx - Umleitung - Um eine erfolgreiche Bearbeitung der Anfrage sicherzustellen, sind weitere Schritte seitens des Clients erforderlich.
4xx - Client-Fehler - Eher Client-Fehler, aber nicht klar von den so genannten Server-Fehlern abzugrenzen.
5xx - Server-Fehler - Eher Server-Fehler, aber nicht klar von den so genannten Client-Fehlern abzugrenzen.
Alle kennen wohl den bekannten 404 Fehlercode, wenn etwas nicht gefunden wurde. Manche würden das jetzt als Serverfehler abschreiben, doch der Server hat ja ordnungsgemäß geantwortet und sagt, dass dort keine Dateien vorhanden sind. Es liegt also ein Fehler am Client vor, welcher sich z.B. vertippt hat. Es ist allerdings nicht klar zuzuordnen, ob ein 4xx Code wirklich immer nur ein Client-Fehler ist.
Zurück zum Script. Laut den Fehlercodes müssten wir 2xx und 3xx als “erreichbar” ansehen. 1xx, 4xx und 5xx sollten wir als “unerreichbar” deklarieren.
Nachdem wir den Array erhalten haben, kürzen wir das Wichtigste mit substr() raus – nämlich den reinen Antwortcode. Zusätzlich bauen wir noch gleich eine Abfrage rein, ob das https:// überhaupt dranhängt. Ansonsten wird es hinzugefügt.
function url_online($url) { $url = (substr($url, 0, 7) != 'https://' ? 'https://'.$url : $url ); $headers = get_headers($url); return substr($headers[0], 9, 3); }
Fast fertig
Uns wird jetzt bei Aufruf der Funktion der reine 3-stellige Antwortcode zurückgeliefert. Jetzt fehlt nur noch die Abfrage, welcher Code welches Ergebnis ausgeben soll. Da es ein String ist, können wir uns auch einzelne Zeichen direkt anschauen. Wir betrachten also nur die erste Ziffer.
<?php
function url_online($url)
{
$url = (substr($url, 0, 7) != 'https://' ? 'https://'.$url : $url );
$headers = get_headers($url);
$headers = substr($headers[0], 9, 3);
if ($headers[0]=="2" || $headers[0]=="3") {
return $url." scheint online zu sein!";
}
else
{
return $url." scheint offline zu sein!";
}
}
?>
Nun erhalten wir via
<?php
echo url_online(“https://yakuza112.org”);
?>
die Status Ausgabe der Webseite.