7 Stimmen

Wie funktioniert header()?

Ein kleiner Kontext:
Ich musste PHP-Skripte in einem Browser ausführen, aber ich wollte mir nicht die Mühe machen, einen Server zu installieren und den Aufwand zu betreiben, der mit dem Betrieb eines Servers auf meinem Computer verbunden ist, einschließlich Firewalls, bla bla bla.

Also habe ich stattdessen meinen eigenen Server geschrieben. Es ist ein einfaches PHP-Skript, das auf Verbindungen an Port 80 meiner LAN-IP wartet. Es empfängt die HTTP-Anfrage und startet ein zweites PHP-Skript mit exec - damit ich Änderungen leicht vornehmen kann, ohne das Serverskript neu starten zu müssen. Dieses zweite PHP-Skript parst die Anfrage und schließlich include ist das Skript, das tatsächlich aufgerufen wurde. Es ruft die Ausgabe von dort ab und sendet die Antwort mit den entsprechenden Kopfzeilen (die ich ändern kann) zurück an den Browser.

Ja, es ist ein Chaos, aber es funktioniert. Es tut, was ich tun muss.

Und nun die Frage:
Ich kann nicht verwenden header() . Es scheint keinen Einfluss darauf zu haben, was über die Socket-Verbindung an den Browser zurückgesendet wird. Ich habe stattdessen eine setheader() Funktion und speichern Sie die Kopfzeilen in einem Array, das der Antwort vorangestellt wird.

Ich würde gerne wissen, wie die header() Funktion tatsächlich intern funktioniert, so dass ich diese Funktion anstelle meiner "gehackten" Funktion verwenden könnte.

2voto

netcoder Punkte 64375

En header() Funktion wird vom CLI SAPI völlig ignoriert. Sie hat jedoch Auswirkungen auf die Apache- und CGI-SAPIs.

Einfach ausgedrückt, implementiert das CLI SAPI keine Logik in der sapi_*_header_* Funktionen. Zum Beispiel für das CLI SAPI, in php_cli.c :

static int sapi_cli_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) /* {{{ */
{
    /* We do nothing here, this function is needed to prevent that the fallback
    * header handling is called. */
    return SAPI_HEADER_SENT_SUCCESSFULLY;
}
/* }}} */

Alle diese Funktionen geben im Grunde NULL , 0 oder eine gefälschte Erfolgsmeldung.

Für das CGI SAPI, in cgi_main.c :

static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
{
    char buf[SAPI_CGI_MAX_HEADER_LENGTH];
    sapi_header_struct *h;
    zend_llist_position pos;
    zend_bool ignore_status = 0;
    int response_status = SG(sapi_headers).http_response_code;

    // Lots of other code...
}

Sie können dies ganz einfach mit der Funktion php-cgi binär und einige Array-Manipulationen:

server.php

$script_to_run = 'script.php';
exec('php-cgi '.escapeshellarg($script_to_run), $output);
$separator = array_search("", $output);

$headers = array_slice($output, 0, $separator);
$body = implode("\r\n", array_slice($output, $separator+1));

print_r($headers);
print $body;

skript.php

header('Content-Type: text/plain');
echo 'Hello, World!';

Sortie :

Array
(
    [0] => X-Powered-By: PHP/5.3.8
    [1] => Content-Type: text/plain
)
Hello, World!

1voto

Alessandro Desantis Punkte 13768

En header() Funktion funktioniert genauso wie Ihre Implementierung: Sie sendet nur einfache Text-Header in der Antwort, vor dem Inhalt der Seite (deshalb wird ein Fehler ausgegeben, wenn bereits ein Inhalt an den Client gesendet wurde). Ich denke also, Sie machen es richtig. Wie auch immer, Sie haben einige Probleme bei Ihrer Implementierung. Ich denke, es wäre viel einfacher gewesen, einen Webserver zu installieren.

0voto

SergeS Punkte 11008

Und verwenden Sie korrekte CGI-Aufrufe? - Ansonsten funktionieren die meisten HTTP-bezogenen Funktionen nicht in PHP - und CGI ist immer noch nicht so gut wie Bibliotheksaufrufe von Apache oder IIS

Warum nehmen Sie nicht einfach EasyPHP oder etwas Ähnliches?

PS Was meinen Sie mit "Parsing-Anfrage"?

0voto

Michael Mior Punkte 27045

Das eigentliche Senden der Header wird von der SAPI-Schicht (Server-API) von PHP durchgeführt. Beispiele für SAPIs sind mod_php für Apache und die CLI-Version von PHP, die ausgeführt wird, wenn Sie exec . Im Falle des CLI-SAPI ist das Senden von Headern ein Noop, da es normalerweise keinen Sinn macht, HTTP-Header für ein Skript anzuzeigen, das über die Befehlszeile ausgeführt wird.

Versuchen Sie es mit php-cgi als Binärdatei anstelle von PHP. Das CGI SAPI sollte die richtigen Header ausgeben.

0voto

David Schwartz Punkte 172718

Das SAPI-Modul (der Code, der das PHP-Skript aufruft) muss entscheiden, was mit den Headern geschehen soll. Das CLI-SAPI, das Sie wahrscheinlich verwenden, ignoriert einfach alle vom Skript gesetzten Header. Das CGI-SAPI, das Sie mit der Option php-cgi gibt sie standardmäßig aus, unterstützt aber eine Befehlszeilenschnittstelle, um sie zu unterdrücken. Idealerweise schreiben Sie einfach Ihr eigenes SAPI-Modul, das eine korrekte Schnittstelle zu Ihrem Webserver hat.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X