媒介
PHP从5.4开端,就提供了一个内置的web效劳器。
这个次要是用来做内陆的开发用的。不克不及用于线上环境。如今我就引见一下这个对象若何应用。
根底使用
起首咱们假设名目目次是/home/baoguoxiao/www/php/demo
,外界可拜访的目次是/home/baoguoxiao/www/php/demo/public
。而后拜访的端口是8000
,入口文件是index.php
以及index.html
。那末咱们能够执行以下饬令:
cd /home/baoguoxiao/www/php/demo/public php -S localhost:8000
而后这个时分就能够失常拜访了。
那末如今有个成绩,就是莫非每一次必需要进入public
文件夹能力启动web效劳器吗,其实咱们能够指定根目次的,那末能够应用以下饬令:
cd /home/baoguoxiao/www/php/demo php -S localhost:8000 -t public/
那末如今有一个成绩就是说,假如咱们应用了单入口,并且仍是用了PATHINFO模式。那末下面的可能就有成绩了。
对此,咱们能够应用以下计划:
cd /home/baoguoxiao/www/php/demo php -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/ServeCo妹妹and.php
/** * 执行饬令. * * @return int * * @throws \Exception */ public function handle() { // 切换门路到 public 目次 chdir(public_path()); // 正在饬令台进行输入相干内容 $this->line("<info>Laravel development server started:</info> <http://{$this->host()}:{$this->port()}>"); // 执行内部顺序,而且 $status 为零碎的前往状态 passthru($this->serverCo妹妹and(), $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 serverCo妹妹and() { 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 ./public php -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 http://%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 门路为: // vendor\symfony\web-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 vendor\symfony\web-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效劳器的具体内容,更多请存眷资源魔其它相干文章!
标签: php php开发教程 php开发资料 php开发自学 web服务器