本文为joshua317原创文章,转载请注明:转载自joshua317博客 Laravel 如何使用 PHP 内置的服务器启动服务 - joshua317的博客
在Laravel项目中,如果你在本地安装了 PHP, 并且你想使用 PHP 内置的服务器来为你的应用程序提供服务,则可以使用 Artisan 命令 serve 。该命令会在 http://localhost:8000
上启动开发服务器
一、如何启动PHP内置服务器?
php artisan serve
你也可以指定host和port进行启动,主要使用--host和--port参数
1.1 指定端口号
php artisan serve --port 8001
1.2 指定host,可以使用ip,也可以使用域名的形式
php artisan serve --host 127.0.0.2 --port 8001
二、php artisan serve命令如何运行的?
有人比较好奇为什么执行这个命令就可以运行服务了呢?
其实从 PHP 5.4 版本开始,PHP 就已经内置(built in)了一个 web server,并且,Laravel 的 artisan 命令也支持这个内置web server,这让快速启动服务变得更高效了。当然,如果要部署到生产服务器上的话,还是要安装 apache 或 nginx 之类的 web server 的。
接下来我们来分析下laravel的命令:php artisan serve
2.1 源文件ServeCommand.php
注意:此次laravel项目是基于6.20.26版本
源文件是src/Illuminate/Foundation/Console/ServeCommand.php
<?php
namespace Illuminate\Foundation\Console;
use Illuminate\Console\Command;
use Illuminate\Support\Env;
use Illuminate\Support\ProcessUtils;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Process\PhpExecutableFinder;
class ServeCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'serve';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Serve the application on the PHP development server';
/**
* The current port offset.
*
* @var int
*/
protected $portOffset = 0;
/**
* Execute the console command.
*
* @return int
*
* @throws \Exception
*/
public function handle()
{
chdir(public_path());
$this->line("<info>Laravel development server started:</info> http://{$this->host()}:{$this->port()}");
passthru($this->serverCommand(), $status);
if ($status && $this->canTryAnotherPort()) {
$this->portOffset += 1;
return $this->handle();
}
return $status;
}
/**
* Get the full server command.
*
* @return string
*/
protected function serverCommand()
{
return sprintf('%s -S %s:%s %s',
ProcessUtils::escapeArgument((new PhpExecutableFinder)->find(false)),
$this->host(),
$this->port(),
ProcessUtils::escapeArgument(base_path('server.php'))
);
}
/**
* Get the host for the command.
*
* @return string
*/
protected function host()
{
return $this->input->getOption('host');
}
/**
* Get the port for the command.
*
* @return string
*/
protected function port()
{
$port = $this->input->getOption('port') ?: 8000;
return $port + $this->portOffset;
}
/**
* Check if command has reached its max amount of port tries.
*
* @return bool
*/
protected function canTryAnotherPort()
{
return is_null($this->input->getOption('port')) &&
($this->input->getOption('tries') > $this->portOffset);
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['host', null, InputOption::VALUE_OPTIONAL, 'The host address to serve the application on', '127.0.0.1'],
['port', null, InputOption::VALUE_OPTIONAL, 'The port to serve the application on', Env::get('SERVER_PORT')],
['tries', null, InputOption::VALUE_OPTIONAL, 'The max number of ports to attempt to serve from', 10],
];
}
}
PHP
Copy
2.2 源文件分析
我们通过handle()方法可以得知
2.2.1 更改执行根目录
首先使用 chdir() 将目录改变至 public/ 目录
chdir(public_path());
PHP
Copy
这是根据 $this->laravel->publicPath() 代码的 publicPath() 来的,这个方法的源码位于 Illuminate\Foundation\Application 中
function public_path($path = '')
{
return app()->make('path.public').($path ? DIRECTORY_SEPARATOR.ltrim($path, DIRECTORY_SEPARATOR) : $path);
}
PHP
Copy
<?php
namespace Illuminate\Foundation;
use Closure;
use Illuminate\Container\Container;
use Illuminate\Contracts\Foundation\Application as ApplicationContract;
use Illuminate\Contracts\Http\Kernel as HttpKernelContract;
use Illuminate\Events\EventServiceProvider;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables;
use Illuminate\Foundation\Events\LocaleUpdated;
use Illuminate\Http\Request;
use Illuminate\Log\LogServiceProvider;
use Illuminate\Routing\RoutingServiceProvider;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Env;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;
use RuntimeException;
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\HttpKernelInterface;
class Application extends Container implements ApplicationContract, HttpKernelInterface
{
/**
* The Laravel framework version.
*
* @var string
*/
const VERSION = '6.20.36';
/**
* The base path for the Laravel installation.
*
* @var string
*/
protected $basePath;
/**
* Indicates if the application has been bootstrapped before.
*
* @var bool
*/
protected $hasBeenBootstrapped = false;
/**
* Indicates if the application has "booted".
*
* @var bool
*/
protected $booted = false;
/**
* The array of booting callbacks.
*
* @var callable[]
*/
protected $bootingCallbacks = [];
/**
* The array of booted callbacks.
*
* @var callable[]
*/
protected $bootedCallbacks = [];
/**
* The array of terminating callbacks.
*
* @var callable[]
*/
protected $terminatingCallbacks = [];
/**
* All of the registered service providers.
*
* @var \Illuminate\Support\ServiceProvider[]
*/
protected $serviceProviders = [];
/**
* The names of the loaded service providers.
*
* @var array
*/
protected $loadedProviders = [];
/**
* The deferred services and their providers.
*
* @var array
*/
protected $deferredServices = [];
/**
* The custom application path defined by the developer.
*
* @var string
*/
protected $appPath;
/**
* The custom database path defined by the developer.
*
* @var string
*/
protected $databasePath;
/**
* The custom storage path defined by the developer.
*
* @var string
*/
protected $storagePath;
/**
* The custom environment path defined by the developer.
*
* @var string
*/
protected $environmentPath;
/**
* The environment file to load during bootstrapping.
*
* @var string
*/
protected $environmentFile = '.env';
/**
* Indicates if the application is running in the console.
*
* @var bool|null
*/
protected $isRunningInConsole;
/**
* The application namespace.
*
* @var string
*/
protected $namespace;
/**
* Create a new Illuminate application instance.
*
* @param string|null $basePath
* @return void
*/
public function __construct($basePath = null)
{
if ($basePath) {
$this->setBasePath($basePath);
}
$this->registerBaseBindings();
$this->registerBaseServiceProviders();
$this->registerCoreContainerAliases();
}
/**
* Get the version number of the application.
*
* @return string
*/
p