PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : HTTP-Status-Code ermitteln


Small-Talk
10.02.2009, 00:41:37
hi,

habt ihr eine Idee, wie man den gesendeten HTTP-Status-Code ermitteln kann ?
Der Hintergrund ist der, dass ich ein Cache-Objekt habe, welches die gesamte Seite Cached und natürlich bei Status-Codes wie 304 Not Modified den Kontent nicht cachen soll bzw. bei anderen Status-Codes wieder den richtigen header mitschicken muss.

Gestartet wird der das Caching einfach mit "$cache->start()" und die methode aktiviert den outputbuffer mit callback auf eine weitere interne methode die wiederum den gesendeten kontent einfach in eine datei schreibt und zurück gibt und die gesendeten HTTP-Header abfragt. Nur leider fehlt mir bei der php-funktion headers_send der status-code :(

Mit den Streams php://stdout & php://output habe ich es auch schon probiert, aber ohne erfolg.

cortex
10.02.2009, 09:08:53
wie wär's mit get_headers( ) ?

http://de.php.net/manual/de/function.get-headers.php

ansonsten ist der dienst HTTP auch sehr interessant:

http://de.php.net/manual/de/book.http.php

cx

Small-Talk
10.02.2009, 20:36:34
hi cortex,

die links sind zwar gut gemeint, aber ich möchte nicht die http-header einer entfernten url ermitteln, sonder die, die das eigene php-skript an den Browser sendet/gesendet hat.

Da ich eine Bibliothek schreibe habe ich kein direkten zugriff über die Skripte, die diese dann einsetzen.

Hier mal ein mini-beispiel-skript:

<?php

require_once 'lib/page_cache';
$pageCache = new PageCache();

// Wenn Cache noch nicht existiert:
// -> Startet den output-buffer mittels op_start inkl. callback
// Wenn cache existiert
// -> sende die gecachten Header und das bild
// -> stoppe das Skript
$pageCache->start();

try {
$img = new Image('test.jpg');
$img->fit(100, 100);
header('Content-Type: image/jpeg');
echo $img;
} catch (ImageNotFoundException $e) {
header('HTTP/1.1 404 Not found');
header('Content-Type: image/gif');
readfile('transparent.gif');
}

// am ende des Skripts wird automatisch der callback des output-buffers gestartet.
// dieser muss alle an den browser gesendeten daten inkl. die gesendeten http-header
// cachen.

urvater
10.02.2009, 22:37:21
Will hier nicht erfahrenen Schreibern vorgreifen aber soweit ich das begriffen habe word doch der Status-Code selbst vom Server gesendet.
Somit sollte man nur einen Einfluss auf den Statuscode haben, wenn man ihn absichtlich ändern will.

Aller Falsche Anfrage an die seite sende Status 400

cortex
11.02.2009, 08:47:46
sorry, falls ich dein anliegen nicht korrekt interpretiere - aber:

die kontrolle über den status-header hast du doch bereits innerhalb deines eigenen skriptes durch die exception. du selbst bestimmst doch, welcher header gesendet wird - wozu willst du eine aktion, die du selbst auslöst (und selbst kontrollierst) nochmal prüfen?

stehe ich evtl. auf dem schlauch ?

cx

Small-Talk
11.02.2009, 19:02:56
@cortex:
Wie schon gesagt, ich scheibe ne kleine Bibliothek, die in anderen Skripten möglichst einfach eingebunden werden soll. Das heißt nicht, dass die lib in eines von meinen Skripten eingebunden wird.

@urvater:
Stimmt schon, das der httpd die header schickt, aber wenn er mit PHP läuft kann man die header mit php ändern ( header('HTTP/1.1 [CODE] [MSG]') ). PHP schickt die heder dann weiter an den httpd und dieser gibt sie letztendlich aus.
Trotzdem hält php die header vor und schickt sie erst beim ende des scripts bzw. beim ersten output an den httpd weiter. Nach der php-doku kann man mit headers_list die header abfragen die php weitergibt, aber in dem array fehlt der http status code :(


<?php

headers_list(); // -> leeres array

header('Content-Type: text/html');
headers_list(); // -> array(1) { [0]=> string(23) "Content-Type: text/html" }

header('HTTP/1.1 404 Not Found');
headers_list(); // -> array(1) { [0]=> string(23) "Content-Type: text/html" }
// erwartet: array(2) { [0]=> string(23) "HTTP/1.1 404 Not Found", [1]=> string(23) "Content-Type: text/html" }


Ich hoffe das war jetzt verständlich

DokuLeseHemmung
11.02.2009, 21:55:55
aber in dem array fehlt der http status code :(
Weil der httpd die Header komplettiert.

Small-Talk
11.02.2009, 22:48:11
Weil der httpd die Header komplettiert.

aber php selbst weiß doch was es schickt, wenn das skript keinen gesonderten status code schicken würde ich es ja verstehen.

xabbuh
12.02.2009, 10:03:50
aber php selbst weiß doch was es schickt, wenn das skript keinen gesonderten status code schicken würde ich es ja verstehen.
PHP schickt standardmäßig aber keinen entsprechend Header, wenn du diesen nicht mit header() o.ä. modifizierst.

cortex
12.02.2009, 10:16:07
ich glaube, wir drehen uns im kreis...

cx

Small-Talk
12.02.2009, 18:44:19
PHP schickt standardmäßig aber keinen entsprechend Header, wenn du diesen nicht mit header() o.ä. modifizierst.

Richtig, deswege könnte ich davon ausgehen, dass immer ein bestimmter header (status-code) an den browser gesendet wird, aber wenn ich den header mit "header()" modifiziere schickt php ja einen anderen status code und genau den brauche ich.

xabbuh
13.02.2009, 09:53:09
EDIT: entfernt

DeadLord
15.02.2009, 12:14:21
ENTFERNT WAR DOPPELPOST

DeadLord
15.02.2009, 12:16:44
eventuell hilft dir dieses Script

<?
function http_test_existance(
$url,
$timeout = 10
) {
$timeout = (int)round($timeout/2+0.00000000001);
$return = array();

### 1 ###
$inf = parse_url($url);

if (!isset($inf['scheme']) or $inf['scheme'] !== 'http') return array('status' => -1);
if (!isset($inf['host'])) return array('status' => -2);
$host = $inf['host'];

if (!isset($inf['path'])) return array('status' => -3);
$path = $inf['path'];
if (isset($inf['query'])) $path .= '?'.$inf['query'];

if (isset($inf['port'])) $port = $inf['port'];
else $port = 80;

### 2 ###
$pointer = fsockopen($host, $port, $errno, $errstr, $timeout);
if (!$pointer) return array('status' => -4, 'errstr' => $errstr, 'errno' => $errno);
socket_set_timeout($pointer, $timeout);

### 3 ###
$head =
'HEAD '.$path.' HTTP/1.1'."\r\n".
'Host: '.$host."\r\n";

if (isset($inf['user']))
$head .= 'Authorization: Basic '.
base64_encode($inf['user'].':'.(isset($inf['pass']) ? $inf['pass'] : ''))."\r\n";
if (func_num_args() > 2) {
for ($i = 2; $i < func_num_args(); $i++) {
$arg = func_get_arg($i);
if (
strpos($arg, ':') !== false and
strpos($arg, "\r") === false and
strpos($arg, "\n") === false
) {
$head .= $arg."\r\n";
}
}
}
else $head .=
'User-Agent: Selflinkchecker 1.0 (http://aktuell.selfhtml.org/artikel/php/existenz/)'."\r\n";

$head .=
'Connection: close'."\r\n"."\r\n";

### 4 ###
fputs($pointer, $head);

$response = '';

$status = socket_get_status($pointer);
while (!$status['timed_out'] && !$status['eof']) {
$response .= fgets($pointer);
$status = socket_get_status($pointer);
}
fclose($pointer);
if ($status['timed_out']) {
return array('status' => -5, '_request' => $head);
}

### 5 ###
$res = str_replace("\r\n", "\n", $response);
$res = str_replace("\r", "\n", $res);
$res = str_replace("\t", ' ', $res);

$ares = explode("\n", $res);
$first_line = explode(' ', array_shift($ares), 3);

$return['status'] = trim($first_line[1]);
$return['reason'] = trim($first_line[2]);

foreach ($ares as $line) {
$temp = explode(':', $line, 2);
if (isset($temp[0]) and isset($temp[1])) {
$return[strtolower(trim($temp[0]))] = trim($temp[1]);
}
}
$return['_response'] = $response;
$return['_request'] = $head;

return $return;

}
?>

dieses script meinetwegen per include einbinden oder direkt mit in die datei und so aufrufen


$url = "DEINE ZU PRÜFENDE ADRESSE MIT HTTP:// DAVOR";
$result = http_test_existance($url); //AUFRUF DES SCRIPTS
if(($result['status'] == "500") OR ($result['status'] == "404") OR ($result['status'] == "503"))
{
echo "SEITE NICHT ERREICHBAR";
}
else
{
echo "SEITE ERREICHBAR";
}

Sollte so funktionieren wenn nicht pm oder hier melden

cortex
15.02.2009, 12:36:15
$url = "DEINE ZU PRÜFENDE ADRESSE MIT HTTP:// DAVOR";
$result = http_test_existance($url); //AUFRUF DES SCRIPTS
if(($result['status'] == "500") OR ($result['status'] == "404") OR ($result['status'] == "503"))
{
echo "SEITE NICHT ERREICHBAR";
}
else
{
echo "SEITE ERREICHBAR";
}


die ergebnis-meldung des skripts weckt bei mir den leisen verdacht, dass du nicht wirklich weisst, was das anliegen des op war...

cx

DeadLord
15.02.2009, 13:37:39
Andere Möglichkeit ist

echo $result['status'];

aber das sollte man im fortgeschrittenen Bereich schon selber hinbekommen

cortex
15.02.2009, 13:41:18
der op wollte den gesendeten status-header eines laufenden / abgelaufenden skripts abfangen. er wollte imho nicht testen, ob ein server erreichbar ist .-

cx

DeadLord
15.02.2009, 13:54:21
ok habe ich wohl falsch verstanden