Facebook
Twitter
Google+
Kommentare
17

Http Status Code mit PHP auslesen

Heute mal wieder was aus der Praxis,  mal wieder etwas mit Code. Da ich derzeit im Qualitätsmanagement arbeite hat man natürlich eine ganz andere Sicht auf Projekte. Viel Code kommt da nicht mehr zusammen. Letzte Woche hatte ich aber mal wieder ein Anliegen, das ich in PHP verpacken wollte. Meine Anforderungen kann man ja schon aus dem Titel erkennen, ich fasse sie aber trotzdem schnell zusammen.

Ich habe eine Reihe von Webseiten, die für mich eine Black Box sind. Jetzt würde ich gerne rausfinden, ob sie den richtigen HTTP Status Code zurückliefern, denn auch wenn man im Browser alles korrekt eingezeigt bekommt, kann es sein, dass ein 404er im Header angezeigt wird. Für uns Anwender ist das eigentlich ziemlich egal, die Suchmaschinen oder besser die Suchmaschine wird diese Seite aber nicht in den Index mit ausnehmen. Das Testen auf den richtigen Status kann also relativ wichtig sein, wenn man seine Seiten gut positionieren will.

Die meisten PHP Methoden, wie fgets, file oder file_get_contens, kümmern sich nur um den Content eines Http Requests, der Header bleibt hierbei außen vor. Zusätzlich ist es meistens auch nicht erlaubt diese für den Zugriff auf externe Dateien zu verwenden. Hier hilft uns aber ein immer wieder gern verwendetes PHP Modul cURL. cURL ist eigentlich ähnlich zu wget, das ihr wohl alle kennt. Ich kann Dateien aus dem Internet laden, ohne dabei einen Browser verwenden zu müssen.

Gehen wir also davon aus, dass wir cURL installiert haben und es verwenden können. Dann würde unsere Funktion wie folgt aussehen.

public static function getHttpCode( $url )
{
    $ch = curl_init();

    // set URL and other appropriate options
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    curl_exec($ch);
    $info = curl_getinfo($ch);
    curl_close($ch);

    return $info['http_code'];
}

Kein Hexenwerk würde ich mal sagen, trotzdem habe ich in meiner $info Variablen alle Informationen, die ich brauche, um meine Anfrage auf Korrektheit zu überprüfen. Ihr könnt auch diesen Array ja mal genauer ansehen, vielleicht braucht ihr das ein oder andere Element noch an einer anderen Stelle.

Diese Funktion solltet ihr einfach einmak täglich über eure Sitemap laufen lassen, in der Hoffnung, dass ihr kaputte Dateien vor Google findet.

Über den Autor

Nils Langner

Nils Langner ist der Gründer von "the web hates me" und auch der Hauptautor. Im wahren Leben leitet er das Qualitätsmanagementteam im Gruner+Jahr-Digitalbereich und ist somit für Seiten wie stern.de, eltern.de und gala.de aus Qualitätssicht verantwortlich. Nils schreibt seit den Anfängen von phphatesme, welches er ebenfalls gegründet hat, nicht nur für diverse Blogs, sondern auch für Fachmagazine, wie das PHP Magazin, die t3n, die c't oder die iX. Nebenbei ist er noch ein gern gesehener Sprecher auf Konferenzen. Herr Langner schreibt die Texte über sich gerne in der dritten Form.
Kommentare

17 Comments

  1. Das geht auch genauso gut mit dem PHP-stream-wrapper – zumindest ab PHP 5.3:

    $fp = fopen( ‚http://example.com‘ );
    var_dump( stream_get_meta_data( $fp ) );

    Und ueber die stream-context-Optionen lassen sich ja sowieso request-type, und weitere Optionen definieren.

    Reply
  2. Moin Kore, da würde ich doch mal sagen, dass ich wieder einen neuen Grund gefunden habe, mich auf 5.3 zu freuen. Nur leider bin ich mir sicher, dass es noch eine Weile dauert, bis wir es im Produktiveinsatz bei uns verwenden werden. Aber hier im Blog wird PHP 5.3 wohl eine Menge neue Artikel produzieren.

    Reply
  3. Wie Johannes neulich hier geschrieben hat ginge das Auslesen der HTTP-Response-Headers auch mit der globalen Variable $http_response_header nach z.B. file_get_contents($url) (falls man mal das cURL-Modul nicht zur Hand hat).

    Reply
  4. @Dominik: Da warst du leider 30min zu spät 😉 Der Pingback war schneller. Aber ich bin froh, dass ich das ganze in eine Funktion gekapselt habe und ich es jetzt ohne Probleme austauschen kann 😉

    Reply
  5. Was für ein HTTP-Request setzt get_headers() denn ab? Das wird irgendwie nirgends erwähnt. Denn: In meinem verlinkten Post musste ich die Feststellung machen, dass ein paar Applikationen auf einen HEAD-Request mit einem forbidden antworten. Andere wiederum liefern Schrott aus, wenn kein Bekannter User-Agent gesetzt ist (oder schlimmer: Wenn PHP als User-Agent daherkommt).

    Reply
  6. Wie wäre es einen Socket mit fsockopen zu erstellen und dann den HTTP-Request zu senden?
    Man ist unabhängig von Curl und kann mit jedem Header rumspielen wie man will.

    Reply
  7. Wenn man dann noch die Funktion get_headers( $url ); erweitert, also einen weiteren parameter anhängt get_headers( $url, 1 );, werden die keys mit dem Namen besetzt anstelle von Indexzahlen (also anstelle von [1] => ‚text/xml‘ steht dort nun [Content-Type] => ‚text/xml‘). Hilft zB sehr bei debuggen mit print_r oder var_dump.

    So kommt man auch nicht unbedingt durcheinander, da nciht alle server alles in der immer gleichen reihenfolge zurücschicken.

    Abgesehen davon funktioniert das erst ab PHP 5… leider. Ansonten halt den curkl code nehmen.

    Reply
  8. ich glaube ich schreibe heute Abend noch einen Artikel „Die 120 Methoden einen HTTP Header auszulesen“. Ich veröffentliche den dann aber erst in 4 Wochen oder so, dann denken alle, die Ideen kamen von mir 😉

    Reply
  9. Wenn ihr die 120 Möglichkeiten beisammen habt, bitte auch ein kleiner Ausflug zu den „performanten“ Varianten.. im produktiven Einsatz freut man sich dann über jede gesparte MS 😉

    Reply
  10. @Nils wenn du es nicht neu erfinden möchtest, kannst du auch das PEAR-Paket HTTP-Request nutzen. Dort wird der socket implementiert und man ist fast genauso flexibel.

    Reply
  11. Der Firefox in aktueller Version zeigt den Inhalt von 404-Dokumenten übrigens inzwischen nicht mehr an. Sei nur so der Vollständigkeit wegen erwähnt.

    Reply

Leave a Comment.

Link erfolgreich vorgeschlagen.

Vielen Dank, dass du einen Link vorgeschlagen hast. Wir werden ihn sobald wie möglich prüfen. Schließen