亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > PHP > 正文

PHP之內置web服務器

2020-03-22 17:59:19
字體:
來源:轉載
供稿:網友

 

 

前言

PHP從5.4開始,就提供了一個內置的web服務器。

這個主要是用來做本地的開發用的。不能用于線上環境。現在我就介紹一下這個工具如何使用。

基礎應用

首先我們假定項目目錄是/home/baoguoxiao/www/php/demo,外界可訪問的目錄是/home/baoguoxiao/www/php/demo/html' target='_blank'>public。然后訪問的端口是8000,入口文件是index.phpindex.html。那么我們可以執行如下命令:

cd /home/baoguoxiao/www/php/demo/publicphp -S localhost:8000

然后這個時候就可以正常訪問了。

那么現在有個問題,就是難道每次必須要進入public文件夾才能啟動web服務器嗎,其實我們可以指定根目錄的,那么可以使用如下命令:

cd /home/baoguoxiao/www/php/demophp -S localhost:8000 -t public/

那么現在有一個問題就是說,如果我們使用了單入口,而且還是用了PATHINFO模式。那么上面的可能就有問題了。

對此,我們可以使用如下方案:

cd /home/baoguoxiao/www/php/demophp -S localhost:8000 router.php

router.php 文件的代碼

/** * 對URL進行解析,并獲取請求的文件名 */$uri = urldecode(parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH));/** * 判斷是否存在該文件,如果不存在,則直接繼續加載入口文件 */if ($uri !== "/" && file_exists(__DIR__ . "$uri")) {    return false;}/** * 加載入口文件 */require_once "./index.php";

通過這個路由文件,我們就可以支持目前常用的開發情況了。

框架參考

上面的方式是我們自己的實現,那么我們也可以看看相關知名框架的實現方法。

比如 Laravel 和 Symfony。

Laravel

在Laravel中的安裝一節中介紹了一個命令可以使用PHP內置web服務器實現外部訪問的命令。實現的命令是:

php artisan serve

我們可以看一下相關代碼:

具體的文件路徑為:vendor/laravel/framework/src/Illuminate/Foundation/Console/ServeCommand.php

/** * 執行命令. * * @return int * * @throws Exception */public function handle(){    // 切換路徑到 public 目錄    chdir(public_path());    // 在命令臺進行輸出相關內容    $this->line("<info>Laravel development server started:</info> <https://{$this->host()}:{$this->port()}>");    // 執行外部程序,并且 $status 為系統的返回狀態    passthru($this->serverCommand(), $status);    // $status 為0 表示執行正常, 為其他大于0的數字表示出現了錯誤,有可能是端口被搶占了,這個時候就會接著判斷是否進行再次嘗試    if ($status && $this->canTryAnotherPort()) {        // 對綁定的端口號加1 默認是8000, 如果失敗則重試端口號為8001,再次失敗重試端口號為8002,以此類推。        $this->portOffset += 1;        // 再次調用此程序        return $this->handle();    }    // 返回狀態值    return $status;}/** * 獲取完整的 server 命令. * * @return string */protected function serverCommand(){    return sprintf('%s -S %s:%s %s',                // 獲取PHP可執行命令的路徑        ProcessUtils::escapeArgument((new PhpExecutableFinder)->find(false)),                // 獲取需要綁定的host        $this->host(),        // 獲取需要綁定的端口        $this->port(),        // 對需要執行的參數進行轉義處理。這里的 server 就是我們之前說的路由文件,它在項目的根路徑下        ProcessUtils::escapeArgument(base_path('server.php'))    );}

對上面的命令進行翻譯一下,實際上就是執行的

cd ./publicphp -S 0.0.0.0:8000 ../server.php

note:

這里我們可以看到一個區別就是之前我自己寫的代碼,host 都是 localhost, 但是這里寫的是 0.0.0.0。這兩個有什么區別呢?

其實區別很簡單,比如我之前寫的 localhost 綁定的ip 是 127.0.0.1, 這個相當于一個回環地址,那么我們就只允許本機的IP進行訪問。而 0.0.0.0,則表示我們對ip不進行限制,所有的IP都可以進行訪問。

那我們接著再來看看項目根目錄下面的server.php:

/** * Laravel - A PHP Framework For Web Artisans * * @package  Laravel * @author   Taylor Otwell <taylor@laravel.com> */$uri = urldecode(    parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));// 這個文件允許我們從內置 PHP web 服務器中模擬 Apache 的 "mod_rewrite" 功能.// 這提供了一種測試 Laravel 應用程序的便捷方法,// 而無需在此安裝"真正的" web 服務器軟件。if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) {    return false;}require_once __DIR__.'/public/index.php';

發現跟我之前寫的路由文件相同。沒錯,我就是從這里抄過來的。

基本上 Larvel 的實現方法就是這樣了。

Symfony

如果你在使用 Symfony 框架話,發現Symfony有一個組件叫做web-server-bundle,這個組件的作用跟Laravel相同,也是不借助web服務器,實現通過瀏覽器訪問應用程序。

基本的操作可以參考該頁面

我在這里主要說一下Symfony是如何實現的.

在Symfony中有一段代碼是這樣的:

public function start(WebServerConfig $config, $pidFile = null){    // 獲取默認的PID文件位置    $pidFile = $pidFile ?: $this->getDefaultPidFile();    // 判斷是否在運行,如果運行則提示已經在監聽了    if ($this->isRunning($pidFile)) {        throw new RuntimeException(sprintf('A process is already listening on https://%s.', $config->getAddress()));    }    // fork了一個子進程,如果成功,會有兩個進程進行同時執行下面的文件,父進程,也就是當前執行的進程會返回子進程的PID,而子進程則返回的PID為0,    // 如果失敗,則子進程不會創建,并且父進程會返回的pid為-1。更多內容可查看 https://www.php.net/manual/zh/function.pcntl-fork.php    $pid = pcntl_fork();    // 表示fork進程失敗    if ($pid < 0) {        throw new RuntimeException('Unable to start the server process.');    }    // 進入這個判斷,表示執行的是父進程,表示不用繼續向下執行    if ($pid > 0) {        return self::STARTED;    }    // 從此往后是子進程運行,首先通過 posix_setsid 變為守護進程,意思是使其脫離終端的管理,自立門戶,誰也沒辦法管理這個進程,除了PID。    if (posix_setsid() < 0) {        throw new RuntimeException('Unable to set the child process as session leader.');    }    // 創建命令,命令類似Laravel,不過這里的路由文件跟Laravel類似。也是處理加載規則,并加載入口文件。具體的router.php 路徑為:    // vendorsymfonyweb-server-bundle/Resources/router.php    // 下面是禁用輸出并且開始運行    $process = $this->createServerProcess($config);    $process->disableOutput();    $process->start();    // 判斷是否運行成功    if (!$process->isRunning()) {        throw new RuntimeException('Unable to start the server process.');    }    // 寫入PID文件    file_put_contents($pidFile, $config->getAddress());    // 檢測PID文件,如果PID文件刪除了,那么進程就立即退出。    while ($process->isRunning()) {        if (!file_exists($pidFile)) {            $process->stop();        }        sleep(1);    }    // 返回停止的狀態    return self::STOPPED;}/** * 啟動PHP內置web服務器 * @return Process The process */private function createServerProcess(WebServerConfig $config){    // 查找PHP的可執行程序    $finder = new PhpExecutableFinder();    if (false === $binary = $finder->find(false)) {        throw new RuntimeException('Unable to find the PHP binary.');    }    $xdebugArgs = ini_get('xdebug.profiler_enable_trigger') ? ['-dxdebug.profiler_enable_trigger=1'] : [];    // 實例化PHP要執行的命令 php_path -dvariables_order=EGPCS -S 127.0.0.1:8000 vendorsymfonyweb-server-bundle/Resources/router.php    $process = new Process(array_merge([$binary], $finder->findArguments(), $xdebugArgs, ['-dvariables_order=EGPCS', '-S', $config->getAddress(), $config->getRouter()]));    // 設置工作目錄    $process->setWorkingDirectory($config->getDocumentRoot());    // 設置超時時間    $process->setTimeout(null);    // 設置環境變量    if (in_array('APP_ENV', explode(',', getenv('SYMFONY_DOTENV_VARS')))) {        $process->setEnv(['APP_ENV' => false]);        $process->inheritEnvironmentVariables();    }    // 返回相關變量    return $process;}

我在上面的代碼中進行了注釋, 描述了Symfony是如何啟動的.

里面有一個問題就是使用pcntl_fork, 該擴展在Windows中是不受支持的. 所以 Symfony框架會提示使用php bin/console server:run命令運行程序.

未來展望

其實還有一個方式, 就是 Workman 是通過自身的實現的web服務器,它并沒有借助php -S命令。這一塊的代碼我還沒有吃透,并且我覺得這個也可以單獨拎幾章出來講。希望以后有這個機會。

總結

通過我們學習 PHP 命令實現web服務器訪問以及對 Laravel 和 Symfony 框架的分析, 讓我了解到在Windows的開發過程中,我們完全可以借助該方式來擺脫對web服務器的依賴.既能方便我們在Windows環境進行開發并且學習了PHP一個技巧.感覺挺好的.

大家如果對此有什么疑問可以評論進行交流.

更多PHP相關技術文章,請訪問PHP教程欄目進行學習!

以上就是PHP之內置web服務器的詳細內容,更多請關注 其它相關文章!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品视频久久久| 亚洲视屏在线播放| 中文字幕av一区二区三区谷原希美| 国产精品美乳一区二区免费| 中文字幕欧美日韩精品| 狠狠色噜噜狠狠狠狠97| 亚洲精品资源美女情侣酒店| 欧美亚洲日本网站| 国产99久久精品一区二区| 精品亚洲男同gayvideo网站| 丝袜亚洲欧美日韩综合| 欧美性猛交xxxx富婆| 国产成人精品a视频一区www| 亚洲美腿欧美激情另类| 国产成人精品久久二区二区91| 久久久国产91| 欧美精品免费在线| 26uuu另类亚洲欧美日本老年| 欧美激情乱人伦| 国产精品一区二区三区在线播放| 日韩hd视频在线观看| 国产精品高潮粉嫩av| 日本精品一区二区三区在线| 国产91精品在线播放| 精品成人久久av| 日韩av网站大全| 精品欧美国产一区二区三区| 91wwwcom在线观看| 91大神福利视频在线| 亚洲免费视频一区二区| 亚洲激情久久久| 欧美性20hd另类| 中文字幕日韩精品在线| 日韩欧美中文第一页| 精品国内产的精品视频在线观看| 国产精品久久久91| 91av中文字幕| 欧美激情亚洲另类| 中文亚洲视频在线| 疯狂欧美牲乱大交777| 黄色成人在线播放| 成人天堂噜噜噜| 欧美性xxxxx极品娇小| 国产香蕉一区二区三区在线视频| 亚洲精品狠狠操| 午夜精品一区二区三区在线视| 2019中文字幕在线免费观看| 欧美日产国产成人免费图片| 国产精品美腿一区在线看| 亚洲视频欧洲视频| 在线激情影院一区| 久久久久999| 91精品在线观看视频| 国产精品第七十二页| 欧美午夜精品久久久久久浪潮| 美乳少妇欧美精品| 成人av番号网| 久热爱精品视频线路一| 亚洲第一二三四五区| 97国产精品视频人人做人人爱| 亚洲欧美日韩精品久久亚洲区| 久久99精品久久久久久噜噜| 久久久成人的性感天堂| 成人性生交xxxxx网站| 7777免费精品视频| 中文字幕日韩高清| 亚洲天堂男人的天堂| 国内精品视频在线| 日韩av在线免费播放| 伊人久久久久久久久久| 国产精品白丝jk喷水视频一区| 国产精品偷伦一区二区| 欧美壮男野外gaytube| 亚洲欧美激情另类校园| 欧美精品一区二区三区国产精品| 亚洲自拍av在线| 色爱精品视频一区| 精品久久久免费| 奇米4444一区二区三区| 中文字幕精品一区久久久久| 久久成人免费视频| 久久人人爽人人爽人人片亚洲| 最新国产精品拍自在线播放| 欧美成人精品在线视频| 欧美黄色三级网站| 中文字幕日韩欧美在线| 国产成人在线精品| 欧美亚洲成人xxx| 欧美激情第一页xxx| 成人性生交大片免费看小说| 尤物精品国产第一福利三区| 黑人极品videos精品欧美裸| 97**国产露脸精品国产| 欧美中文字幕视频| 久久久综合免费视频| 欧美高清不卡在线| 欧美在线视频a| 福利一区视频在线观看| 国产香蕉一区二区三区在线视频| 欧美精品videos| 中文字幕欧美日韩精品| 成人性生交大片免费看视频直播| 欧美专区在线视频| 亚洲 日韩 国产第一| 中文字幕亚洲欧美| 亚洲欧洲日产国产网站| 日韩精品在线视频观看| 日韩电影大全免费观看2023年上| 日韩国产精品亚洲а∨天堂免| 曰本色欧美视频在线| 国产精品日韩电影| 亚洲成人xxx| 911国产网站尤物在线观看| 美女福利视频一区| 国产亚洲精品高潮| 欧美片一区二区三区| 亚洲国产日韩一区| 久久久亚洲精品视频| 亚洲精品动漫久久久久| 激情久久av一区av二区av三区| 日本精品一区二区三区在线| 亚洲一区二区三区成人在线视频精品| 正在播放欧美视频| 精品中文视频在线| 欧美日韩一区二区免费视频| 久久久成人精品视频| 国产精品高清在线| 国产精品999| 国产成人精品久久二区二区| 日韩av免费在线观看| 欧美裸体xxxx极品少妇软件| 最近2019中文字幕大全第二页| 成人黄色午夜影院| 欧美黑人性生活视频| 欧美性开放视频| 色久欧美在线视频观看| 国产精品一区二区三区久久久| 久久久久久久成人| 亚洲精品wwwww| 国产精品一久久香蕉国产线看观看| 亚洲国产日韩精品在线| 亚洲自拍偷拍视频| 亚洲欧洲日产国码av系列天堂| 欧美插天视频在线播放| 欧美大片免费观看在线观看网站推荐| 97精品一区二区视频在线观看| 国产精品亚洲片夜色在线| 亚洲国内高清视频| 国产精品久久久久久久电影| 欧美国产激情18| 亚洲国产另类 国产精品国产免费| 狠狠爱在线视频一区| 欧美福利视频网站| 亚洲人高潮女人毛茸茸| 一本大道久久加勒比香蕉| 一区二区日韩精品| 成人网页在线免费观看| 91性高湖久久久久久久久_久久99| 在线日韩日本国产亚洲| 国产精品三级美女白浆呻吟| 欧美性极品xxxx娇小| 精品视频www| 亚洲性夜色噜噜噜7777| 精品视频在线导航|