2011-11-10 53 views
7

有點上下文:
我需要在瀏覽器中運行PHP腳本,但我不想去安裝服務器的所有麻煩,並承受在我的計算機上運行服務器的開銷和所有隨之而來的東西,包括防火牆,等等等等。header()如何工作?

因此,我寫了自己的服務器。這是一個簡單的PHP腳本,用於偵聽局域網IP的端口80上的連接,然後在瀏覽器中加載該IP,並且它可以正常工作。它接收HTTP請求並使用exec啓動第二個PHP腳本 - 這樣我就可以輕鬆對其進行更改,而無需重新啓動服務器腳本。這第二個PHP腳本解析請求,最後是實際被調用的腳本include。它從那裏獲取輸出,並將響應返回給瀏覽器,並帶有適當的頭文件(我可以更改)。

是的,這是一團糟,但它的工作原理。它做我需要做的事情。

現在的問題:
我不能使用header()。它似乎對通過套接字連接發送回瀏覽器的內容沒有任何影響。我做了一個setheader()函數,並將數據頭存儲在一個數組中,以作爲響應的前綴。

我想知道header()函數實際上內部是如何工作,所以我可能能夠使用該功能,而不是我的「黑客」之一。

+1

[從手冊:](http://docs.php.net/manual/en/function.header.php)*標題將只有在支持SAPI的SAPI正在使用時纔可以訪問和輸出。* – Gordon

+0

您能否打印由服務器腳本發送給瀏覽器的樣本響應,該響應將包含標題和正文? –

回答

2

CLI SAPI完全忽略了header()函數。但它對Apache和CGI SAPI有影響。

簡而言之,CLI SAPI不會在sapi_*_header_*函數中實現任何邏輯。每例如,對於CLI SAPI,在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; 
} 
/* }}} */ 

所有這些功能基本恢復NULL0或僞造成功的消息。

對於CGI SAPI,在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... 
} 

可以使用php-cgi二進制和一些數組操作很容易使這項工作:

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!'; 

輸出:

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

header()功能的工作原理完全爲你實現的功能:它只是發送純文本標題的響應,網頁的內容之前(這就是爲什麼它會拋出一個錯誤,如果任何內容已經被髮送到客戶端)。所以,我認爲你做的是正確的。無論如何,你在實現中遇到了一些問題。我認爲安裝Web服務器會容易得多。

0

並且你使用正確的CGI風格的調用? - 否則大多數與HTTP相關的函數都不能在PHP中工作 - 而CGI仍然不如Apache或IIS的庫函數最好。

爲什麼不採取EasyPHP或類似的東西?

PS你是什麼意思的「解析請求」?

0

實際的發送頭由PHP的SAPI(服務器API)層執行。示例SAPI包括Apache的mod_php和PHP的CLI版本,當您撥打exec時,將運行該版本。對於CLI SAPI來說,發送標頭是一個noop,因爲通過命令行運行的腳本顯示HTTP標頭通常沒有意義。

嘗試使用php-cgi作爲二進制代替PHP。 CGI SAPI應輸出正確的標題。

0

由SAPI模塊(調用PHP腳本的代碼)決定如何處理標頭。您可能使用的CLI SAPI只會忽略腳本設置的任何標頭。 CGI SAPI可以與php-cgi命令一起使用,默認情況下會輸出它們,但支持命令行界面來抑制它們。理想情況下,您只需編寫與您的Web服務器正確連接的SAPI模塊。

0

一個平常的HTTP響應看起來像這樣:

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> 
.... 

PHP函數header()需要投入的護理 - 嗯, - 頭到響應的第一部分。您可以使用print等來輸出實際的HTML。

現在,如果它是一個PHP腳本,正在播放Apache,這個腳本負責將您的標題行放入其響應中。 header()只有當輸出發送到stdout,而不是定製編寫的插座,這樣,一個PHP,CGI腳本結束後,適當的報頭可以被前置到輸出工作。

0

我知道我會聽起來很蠢,但爲什麼不只是安裝WAMP或燈?這是一個真正的「解壓&運行&瞧」式的解決方案,那真的會饒你麻煩。

相關問題