php 內建的 web 伺服器

LarryHai6發表於2019-01-22

php 內建的 web 伺服器


從 PHP 5.4.0 起,PHP內建了Web伺服器,這對於認為需要Apache或Nginx才能預覽PHP應用的開發者來說又是一個隱藏功能。這個內建的Web伺服器不應該用於生產環境,但對於本地開發來說是個極好的工具。Laravel Valet 起初就是使用這個內建的伺服器,但是在1.1.0版本後將其替換為Caddy(檢視相關新聞)。

1、啟動

這個內建的Web伺服器很容易啟動,開啟終端(Windows下對應是cmd命令列),進入專案根目錄,執行如下命令即可:

php -S localhost:8000

(注意點:要安裝php,並且php是全域性環境)

上述命令會新啟動一個PHP Web伺服器,地址是localhost,監聽的埠是8000,當前所在目錄就是這個Web伺服器的根目錄。

現在,開啟瀏覽器,訪問http://localhost:8000就可以預覽應用了。(執行期間,doc視窗不能關閉!)在Web瀏覽器中瀏覽應用時,每個HTTP請求的資訊都會記錄到終端的標準輸出中,因此我們可以檢視應用是否丟擲了404或500響應:

有時候我們需要在同一區域網中的另一臺裝置中訪問這個伺服器(例如iPad或本地虛擬機器),為此,我們可以把localhost換成0.0.0.0,讓PHP Web伺服器監聽所有介面:

php -S 0.0.0.0:8000

要想停止Web伺服器,可以關閉終端,也可以按Ctrl+C快捷鍵。

2、配置

應用常常需要使用專屬的PHP配置檔案,尤其是對記憶體使用、檔案上傳、分析或對位元組碼快取有特殊要求時,一定要單獨配置,我們可以使用-c選項,讓PHP內建的伺服器使用指定的配置檔案:

php -S localhost:8000 -c app/config/php.ini

3、路由指令碼

PHP內建伺服器明顯遺漏了一個功能:與Apache和Nginx不同,它不支援.htaccess檔案,因此,這個伺服器很難使用多數流行的PHP框架中常見的前端控制器(單一入口檔案index.php,用於轉發所有HTTP請求,現在主流PHP框架如Laravel、Symfony都是這樣)。

PHP內建伺服器使用路由指令碼彌補了這一缺憾,處理每個HTTP請求前,會先執行這個路由指令碼,如果結果為false,返回當前HTTP請求中引用的靜態資源URI,否則會把路由指令碼的執行結果當做HTTP響應主體返回。換句話說,路由指令碼的作用其實和.htaccess一樣。

路由指令碼的用法很簡單,只需要在啟動PHP內建伺服器時指定這個PHP指令碼檔案的路徑即可:

php -S localhost:8000 router.php

關於路由指令碼,有興趣的同學可以研究下Laravel Valet底層的server.phphttps://github.com/laravel/valet/blob/master/server.php)。

4、判斷函式

有時候需要知道PHP指令碼使用的是PHP內建的Web伺服器還是使用傳統的Web伺服器,這樣方便我們為不同伺服器設定不同的響應頭。我們可以使用php_sapi_name()函式檢查使用的是哪個PHP Web伺服器,如果當前指令碼使用的是PHP內建伺服器,則該函式返回字串cli-server

<?php
if (php_sapi_name() == ‘cli-server') {
    // PHP 內建 Web 伺服器
} else {
    // 其他Web伺服器
}

5、缺點

PHP內建的Web伺服器不能在生產環境使用,只能在本地開發環境中使用,這是因為其相比Apache或Nginx有諸多不足:

  • 效能不佳。一次只能處理一個請求,其他請求會受到阻塞。如果某個程式耗時較長(資料庫查詢、遠端API呼叫),則整個Web應用會陷入停頓狀態。
  • 支援媒體型別較少(這一點PHP 5.5.7以後有較大改進)。
  • 路由指令碼僅支援少量的URL重寫,更高階則還是需要Apache或Nginx

相關文章