2011-11-10 14 views
7

Un pequeño contexto:
Necesitaba ejecutar scripts PHP en un navegador, pero no quería tomarme la molestia de instalar un servidor y sufrir la sobrecarga de ejecutar un servidor en mi computadora y todo el cosas que lo acompañan, incluidos los firewalls, bla, bla, bla.¿Cómo funciona header()?

Por lo tanto, escribí mi propio servidor. Es un simple script PHP que escucha las conexiones en el puerto 80 de mi LAN IP, luego solo cargo esa IP en mi navegador y funciona. Recibe la solicitud HTTP e inicia una segunda secuencia de comandos PHP usando exec, esto es para poder realizar cambios fácilmente sin tener que reiniciar la secuencia de comandos del servidor. Esta segunda secuencia de comandos PHP analiza la solicitud, y finalmente include s la secuencia de comandos que en realidad se estaba llamando. Obtiene el resultado desde allí y envía la respuesta al navegador con los encabezados correspondientes (que puedo cambiar).

Sí, es un desastre, pero funciona. Hace lo que necesito que haga.

Ahora la pregunta:
no puedo usar header(). No parece tener ningún efecto sobre lo que se envía de vuelta al navegador a través de la conexión de socket. En su lugar, hice una función setheader() y almaceno los encabezados en una matriz que se agregará a la respuesta.

Me gustaría saber cómo funciona la función header() en realidad internamente, por lo que podría ser capaz de utilizar esa función en lugar de mi función "pirateada".

+1

[Desde el manual:] (*) http://docs.php.net/manual/en/function.header.php encabezados se solo será accesible y se emitirá cuando se use una SAPI que los admita. * – Gordon

+0

¿Puede imprimir la respuesta de muestra que envía la secuencia de comandos del servidor al navegador, que incluirá los encabezados y el cuerpo? –

Respuesta

2

La función header() es totalmente ignorada por CLI SAPI. Sin embargo, tiene un efecto en Apache y CGI SAPI.

En pocas palabras, el CLI SAPI no implementa ninguna lógica en las funciones sapi_*_header_*. Por ejemplo, para el CLI SAPI, en 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; 
} 
/* }}} */ 

Todas esas funciones básicamente regresan NULL, 0 o un mensaje de éxito falso.

Para el CGI SAPI, en 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... 
} 

usted puede hacer fácilmente este trabajo mediante el php-cgi binario y un poco de manipulación de matrices:

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; 

script.php

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

de salida:

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

La función header() funciona exactamente como lo hace su implementación: simplemente envía encabezados de texto sin formato en la respuesta, antes del contenido de la página (es por eso que arrojará un error si ya se envió contenido al cliente). Entonces, creo que lo estás haciendo de la manera correcta. De todos modos, tienes algunos problemas en tu implementación. Creo que instalar un servidor web hubiera sido mucho más fácil.

0

¿Y usa las llamadas correctas al estilo CGI? - De lo contrario, la mayoría de las funciones relacionadas con HTTP no funcionarán en PHP, y aún así CGI no es tan buena como la llamada a la biblioteca de Apache o IIS

¿Por qué simplemente no toma EasyPHP o algo como esto?

PS ¿A qué se refiere con "solicitud de análisis"?

0

Los encabezados de envío reales son realizados por la capa SAPI (API del servidor) de PHP. Ejemplos SAPI incluyen mod_php para Apache y la versión CLI de PHP que se ejecutará cuando llame al exec. En el caso de CLI SAPI, el envío de encabezados es un noop, ya que normalmente no tiene sentido mostrar encabezados HTTP para un script ejecutado sobre la línea de comando.

Intente utilizar php-cgi que el binario en lugar de PHP. El CGI SAPI debería generar los encabezados correctos.

0

Depende del módulo SAPI (el código que invoca el script PHP) decidir qué hacer con los encabezados. El CLI SAPI, que probablemente esté utilizando, simplemente ignora los encabezados establecidos por el script. El CGI SAPI, que puede usar con el comando php-cgi, los emite por defecto, pero admite una interfaz de línea de comando para suprimirlos. Lo ideal es que simplemente escriba su propio módulo SAPI que se conecte correctamente con su servidor web.

0

Una respuesta habitual HTTP se ve así:

HTTP/1.1 200 OK 
Date: Thu, 10 Nov 2011 15:35:27 GMT 
Server: Apache 
Connection: close 
Transfer-Encoding: chunked 
Content-Type: text/html; charset=None 

<!DOCTYPE html> 
<html> 
.... 

La función de PHP header() se encarga de poner - así, - encabezados en la primera parte de la respuesta. El HTML real puede salir usando print y me gusta.

Ahora, si se trata de un script PHP que reproduce Apache, este script es responsable de poner sus líneas de encabezado en su respuesta. header() solo funciona si la salida se envía a stdout y no se escribe de manera personalizada en un socket, de modo que, después de que finalice una secuencia de comandos PHP-CGI, los encabezados apropiados se puedan anteponer a la salida.

0

Sé que voy a sonar estúpido, pero ¿por qué no instalar wamp o lámpara? Es realmente un tipo de solución "descomprimir & ejecutar & voilà", que realmente le ahorraría el problema.