zoukankan      html  css  js  c++  java
  • Laravel 如何使用 PHP 内置的服务器启动服务

    在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 IlluminateFoundationConsole;
    
    use IlluminateConsoleCommand;
    use IlluminateSupportEnv;
    use IlluminateSupportProcessUtils;
    use SymfonyComponentConsoleInputInputOption;
    use SymfonyComponentProcessPhpExecutableFinder;
    
    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

    2.2 源文件分析

    我们通过handle()方法可以得知

    2.2.1 更改执行根目录

    首先使用 chdir() 将目录改变至 public/ 目录

    chdir(public_path());
    PHP

    这是根据 $this->laravel->publicPath() 代码的 publicPath() 来的,这个方法的源码位于 IlluminateFoundationApplication 中

    function public_path($path = '')
    {
        return app()->make('path.public').($path ? DIRECTORY_SEPARATOR.ltrim($path, DIRECTORY_SEPARATOR) : $path);
    }
    PHP
    <?php
    
    namespace IlluminateFoundation;
    
    use Closure;
    use IlluminateContainerContainer;
    use IlluminateContractsFoundationApplication as ApplicationContract;
    use IlluminateContractsHttpKernel as HttpKernelContract;
    use IlluminateEventsEventServiceProvider;
    use IlluminateFilesystemFilesystem;
    use IlluminateFoundationBootstrapLoadEnvironmentVariables;
    use IlluminateFoundationEventsLocaleUpdated;
    use IlluminateHttpRequest;
    use IlluminateLogLogServiceProvider;
    use IlluminateRoutingRoutingServiceProvider;
    use IlluminateSupportArr;
    use IlluminateSupportCollection;
    use IlluminateSupportEnv;
    use IlluminateSupportServiceProvider;
    use IlluminateSupportStr;
    use RuntimeException;
    use SymfonyComponentHttpFoundationRequest as SymfonyRequest;
    use SymfonyComponentHttpKernelExceptionHttpException;
    use SymfonyComponentHttpKernelExceptionNotFoundHttpException;
    use SymfonyComponentHttpKernelHttpKernelInterface;
    
    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 IlluminateSupportServiceProvider[]
         */
        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
         */
        public function version()
        {
            return static::VERSION;
        }
    
        /**
         * Register the basic bindings into the container.
         *
         * @return void
         */
        protected function registerBaseBindings()
        {
            static::setInstance($this);
    
            $this->instance('app', $this);
    
            $this->instance(Container::class, $this);
            $this->singleton(Mix::class);
    
            $this->instance(PackageManifest::class, new PackageManifest(
                new Filesystem, $this->basePath(), $this->getCachedPackagesPath()
            ));
        }
    
        /**
         * Register all of the base service providers.
         *
         * @return void
         */
        protected function registerBaseServiceProviders()
        {
            $this->register(new EventServiceProvider($this));
            $this->register(new LogServiceProvider($this));
            $this->register(new RoutingServiceProvider($this));
        }
    
        /**
         * Run the given array of bootstrap classes.
         *
         * @param  string[]  $bootstrappers
         * @return void
         */
        public function bootstrapWith(array $bootstrappers)
        {
            $this->hasBeenBootstrapped = true;
    
            foreach ($bootstrappers as $bootstrapper) {
                $this['events']->dispatch('bootstrapping: '.$bootstrapper, [$this]);
    
                $this->make($bootstrapper)->bootstrap($this);
    
                $this['events']->dispatch('bootstrapped: '.$bootstrapper, [$this]);
            }
        }
    
        /**
         * Register a callback to run after loading the environment.
         *
         * @param  Closure  $callback
         * @return void
         */
        public function afterLoadingEnvironment(Closure $callback)
        {
            return $this->afterBootstrapping(
                LoadEnvironmentVariables::class, $callback
            );
        }
    
        /**
         * Register a callback to run before a bootstrapper.
         *
         * @param  string  $bootstrapper
         * @param  Closure  $callback
         * @return void
         */
        public function beforeBootstrapping($bootstrapper, Closure $callback)
        {
            $this['events']->listen('bootstrapping: '.$bootstrapper, $callback);
        }
    
        /**
         * Register a callback to run after a bootstrapper.
         *
         * @param  string  $bootstrapper
         * @param  Closure  $callback
         * @return void
         */
        public function afterBootstrapping($bootstrapper, Closure $callback)
        {
            $this['events']->listen('bootstrapped: '.$bootstrapper, $callback);
        }
    
        /**
         * Determine if the application has been bootstrapped before.
         *
         * @return bool
         */
        public function hasBeenBootstrapped()
        {
            return $this->hasBeenBootstrapped;
        }
    
        /**
         * Set the base path for the application.
         *
         * @param  string  $basePath
         * @return $this
         */
        public function setBasePath($basePath)
        {
            $this->basePath = rtrim($basePath, '/');
    
            $this->bindPathsInContainer();
    
            return $this;
        }
    
        /**
         * Bind all of the application paths in the container.
         *
         * @return void
         */
        protected function bindPathsInContainer()
        {
            $this->instance('path', $this->path());
            $this->instance('path.base', $this->basePath());
            $this->instance('path.lang', $this->langPath());
            $this->instance('path.config', $this->configPath());
            $this->instance('path.public', $this->publicPath());
            $this->instance('path.storage', $this->storagePath());
            $this->instance('path.database', $this->databasePath());
            $this->instance('path.resources', $this->resourcePath());
            $this->instance('path.bootstrap', $this->bootstrapPath());
        }
    
        /**
         * Get the path to the application "app" directory.
         *
         * @param  string  $path
         * @return string
         */
        public function path($path = '')
        {
            $appPath = $this->appPath ?: $this->basePath.DIRECTORY_SEPARATOR.'app';
    
            return $appPath.($path ? DIRECTORY_SEPARATOR.$path : $path);
        }
    
        /**
         * Set the application directory.
         *
         * @param  string  $path
         * @return $this
         */
        public function useAppPath($path)
        {
            $this->appPath = $path;
    
            $this->instance('path', $path);
    
            return $this;
        }
    
        /**
         * Get the base path of the Laravel installation.
         *
         * @param  string  $path
         * @return string
         */
        public function basePath($path = '')
        {
            return $this->basePath.($path ? DIRECTORY_SEPARATOR.$path : $path);
        }
    
        /**
         * Get the path to the bootstrap directory.
         *
         * @param  string  $path
         * @return string
         */
        public function bootstrapPath($path = '')
        {
            return $this->basePath.DIRECTORY_SEPARATOR.'bootstrap'.($path ? DIRECTORY_SEPARATOR.$path : $path);
        }
    
        /**
         * Get the path to the application configuration files.
         *
         * @param  string  $path
         * @return string
         */
        public function configPath($path = '')
        {
            return $this->basePath.DIRECTORY_SEPARATOR.'config'.($path ? DIRECTORY_SEPARATOR.$path : $path);
        }
    
        /**
         * Get the path to the database directory.
         *
         * @param  string  $path
         * @return string
         */
        public function databasePath($path = '')
        {
            return ($this->databasePath ?: $this->basePath.DIRECTORY_SEPARATOR.'database').($path ? DIRECTORY_SEPARATOR.$path : $path);
        }
    
        /**
         * Set the database directory.
         *
         * @param  string  $path
         * @return $this
         */
        public function useDatabasePath($path)
        {
            $this->databasePath = $path;
    
            $this->instance('path.database', $path);
    
            return $this;
        }
    
        /**
         * Get the path to the language files.
         *
         * @return string
         */
        public function langPath()
        {
            return $this->resourcePath().DIRECTORY_SEPARATOR.'lang';
        }
    
        /**
         * Get the path to the public / web directory.
         *
         * @return string
         */
        public function publicPath()
        {
            return $this->basePath.DIRECTORY_SEPARATOR.'public';
        }
    
        /**
         * Get the path to the storage directory.
         *
         * @return string
         */
        public function storagePath()
        {
            return $this->storagePath ?: $this->basePath.DIRECTORY_SEPARATOR.'storage';
        }
    
        /**
         * Set the storage directory.
         *
         * @param  string  $path
         * @return $this
         */
        public function useStoragePath($path)
        {
            $this->storagePath = $path;
    
            $this->instance('path.storage', $path);
    
            return $this;
        }
    
        /**
         * Get the path to the resources directory.
         *
         * @param  string  $path
         * @return string
         */
        public function resourcePath($path = '')
        {
            return $this->basePath.DIRECTORY_SEPARATOR.'resources'.($path ? DIRECTORY_SEPARATOR.$path : $path);
        }
    
        /**
         * Get the path to the environment file directory.
         *
         * @return string
         */
        public function environmentPath()
        {
            return $this->environmentPath ?: $this->basePath;
        }
    
        /**
         * Set the directory for the environment file.
         *
         * @param  string  $path
         * @return $this
         */
        public function useEnvironmentPath($path)
        {
            $this->environmentPath = $path;
    
            return $this;
        }
    
        /**
         * Set the environment file to be loaded during bootstrapping.
         *
         * @param  string  $file
         * @return $this
         */
        public function loadEnvironmentFrom($file)
        {
            $this->environmentFile = $file;
    
            return $this;
        }
    
        /**
         * Get the environment file the application is using.
         *
         * @return string
         */
        public function environmentFile()
        {
            return $this->environmentFile ?: '.env';
        }
    
        /**
         * Get the fully qualified path to the environment file.
         *
         * @return string
         */
        public function environmentFilePath()
        {
            return $this->environmentPath().DIRECTORY_SEPARATOR.$this->environmentFile();
        }
    
        /**
         * Get or check the current application environment.
         *
         * @param  string|array  $environments
         * @return string|bool
         */
        public function environment(...$environments)
        {
            if (count($environments) > 0) {
                $patterns = is_array($environments[0]) ? $environments[0] : $environments;
    
                return Str::is($patterns, $this['env']);
            }
    
            return $this['env'];
        }
    
        /**
         * Determine if application is in local environment.
         *
         * @return bool
         */
        public function isLocal()
        {
            return $this['env'] === 'local';
        }
    
        /**
         * Determine if application is in production environment.
         *
         * @return bool
         */
        public function isProduction()
        {
            return $this['env'] === 'production';
        }
    
        /**
         * Detect the application's current environment.
         *
         * @param  Closure  $callback
         * @return string
         */
        public function detectEnvironment(Closure $callback)
        {
            $args = $_SERVER['argv'] ?? null;
    
            return $this['env'] = (new EnvironmentDetector)->detect($callback, $args);
        }
    
        /**
         * Determine if the application is running in the console.
         *
         * @return bool
         */
        public function runningInConsole()
        {
            if ($this->isRunningInConsole === null) {
                $this->isRunningInConsole = Env::get('APP_RUNNING_IN_CONSOLE') ?? (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg');
            }
    
            return $this->isRunningInConsole;
        }
    
        /**
         * Determine if the application is running unit tests.
         *
         * @return bool
         */
        public function runningUnitTests()
        {
            return $this['env'] === 'testing';
        }
    
        /**
         * Register all of the configured providers.
         *
         * @return void
         */
        public function registerConfiguredProviders()
        {
            $providers = Collection::make($this->config['app.providers'])
                            ->partition(function ($provider) {
                                return strpos($provider, 'Illuminate\') === 0;
                            });
    
            $providers->splice(1, 0, [$this->make(PackageManifest::class)->providers()]);
    
            (new ProviderRepository($this, new Filesystem, $this->getCachedServicesPath()))
                        ->load($providers->collapse()->toArray());
        }
    
        /**
         * Register a service provider with the application.
         *
         * @param  IlluminateSupportServiceProvider|string  $provider
         * @param  bool  $force
         * @return IlluminateSupportServiceProvider
         */
        public function register($provider, $force = false)
        {
            if (($registered = $this->getProvider($provider)) && ! $force) {
                return $registered;
            }
    
            // If the given "provider" is a string, we will resolve it, passing in the
            // application instance automatically for the developer. This is simply
            // a more convenient way of specifying your service provider classes.
            if (is_string($provider)) {
                $provider = $this->resolveProvider($provider);
            }
    
            $provider->register();
    
            // If there are bindings / singletons set as properties on the provider we
            // will spin through them and register them with the application, which
            // serves as a convenience layer while registering a lot of bindings.
            if (property_exists($provider, 'bindings')) {
                foreach ($provider->bindings as $key => $value) {
                    $this->bind($key, $value);
                }
            }
    
            if (property_exists($provider, 'singletons')) {
                foreach ($provider->singletons as $key => $value) {
                    $this->singleton($key, $value);
                }
            }
    
            $this->markAsRegistered($provider);
    
            // If the application has already booted, we will call this boot method on
            // the provider class so it has an opportunity to do its boot logic and
            // will be ready for any usage by this developer's application logic.
            if ($this->isBooted()) {
                $this->bootProvider($provider);
            }
    
            return $provider;
        }
    
        /**
         * Get the registered service provider instance if it exists.
         *
         * @param  IlluminateSupportServiceProvider|string  $provider
         * @return IlluminateSupportServiceProvider|null
         */
        public function getProvider($provider)
        {
            return array_values($this->getProviders($provider))[0] ?? null;
        }
    
        /**
         * Get the registered service provider instances if any exist.
         *
         * @param  IlluminateSupportServiceProvider|string  $provider
         * @return array
         */
        public function getProviders($provider)
        {
            $name = is_string($provider) ? $provider : get_class($provider);
    
            return Arr::where($this->serviceProviders, function ($value) use ($name) {
                return $value instanceof $name;
            });
        }
    
        /**
         * Resolve a service provider instance from the class name.
         *
         * @param  string  $provider
         * @return IlluminateSupportServiceProvider
         */
        public function resolveProvider($provider)
        {
            return new $provider($this);
        }
    
        /**
         * Mark the given provider as registered.
         *
         * @param  IlluminateSupportServiceProvider  $provider
         * @return void
         */
        protected function markAsRegistered($provider)
        {
            $this->serviceProviders[] = $provider;
    
            $this->loadedProviders[get_class($provider)] = true;
        }
    
        /**
         * Load and boot all of the remaining deferred providers.
         *
         * @return void
         */
        public function loadDeferredProviders()
        {
            // We will simply spin through each of the deferred providers and register each
            // one and boot them if the application has booted. This should make each of
            // the remaining services available to this application for immediate use.
            foreach ($this->deferredServices as $service => $provider) {
                $this->loadDeferredProvider($service);
            }
    
            $this->deferredServices = [];
        }
    
        /**
         * Load the provider for a deferred service.
         *
         * @param  string  $service
         * @return void
         */
        public function loadDeferredProvider($service)
        {
            if (! $this->isDeferredService($service)) {
                return;
            }
    
            $provider = $this->deferredServices[$service];
    
            // If the service provider has not already been loaded and registered we can
            // register it with the application and remove the service from this list
            // of deferred services, since it will already be loaded on subsequent.
            if (! isset($this->loadedProviders[$provider])) {
                $this->registerDeferredProvider($provider, $service);
            }
        }
    
        /**
         * Register a deferred provider and service.
         *
         * @param  string  $provider
         * @param  string|null  $service
         * @return void
         */
        public function registerDeferredProvider($provider, $service = null)
        {
            // Once the provider that provides the deferred service has been registered we
            // will remove it from our local list of the deferred services with related
            // providers so that this container does not try to resolve it out again.
            if ($service) {
                unset($this->deferredServices[$service]);
            }
    
            $this->register($instance = new $provider($this));
    
            if (! $this->isBooted()) {
                $this->booting(function () use ($instance) {
                    $this->bootProvider($instance);
                });
            }
        }
    
        /**
         * Resolve the given type from the container.
         *
         * @param  string  $abstract
         * @param  array  $parameters
         * @return mixed
         */
        public function make($abstract, array $parameters = [])
        {
            $this->loadDeferredProviderIfNeeded($abstract = $this->getAlias($abstract));
    
            return parent::make($abstract, $parameters);
        }
    
        /**
         * Resolve the given type from the container.
         *
         * @param  string  $abstract
         * @param  array  $parameters
         * @param  bool  $raiseEvents
         * @return mixed
         */
        protected function resolve($abstract, $parameters = [], $raiseEvents = true)
        {
            $this->loadDeferredProviderIfNeeded($abstract = $this->getAlias($abstract));
    
            return parent::resolve($abstract, $parameters, $raiseEvents);
        }
    
        /**
         * Load the deferred provider if the given type is a deferred service and the instance has not been loaded.
         *
         * @param  string  $abstract
         * @return void
         */
        protected function loadDeferredProviderIfNeeded($abstract)
        {
            if ($this->isDeferredService($abstract) && ! isset($this->instances[$abstract])) {
                $this->loadDeferredProvider($abstract);
            }
        }
    
        /**
         * Determine if the given abstract type has been bound.
         *
         * @param  string  $abstract
         * @return bool
         */
        public function bound($abstract)
        {
            return $this->isDeferredService($abstract) || parent::bound($abstract);
        }
    
        /**
         * Determine if the application has booted.
         *
         * @return bool
         */
        public function isBooted()
        {
            return $this->booted;
        }
    
        /**
         * Boot the application's service providers.
         *
         * @return void
         */
        public function boot()
        {
            if ($this->isBooted()) {
                return;
            }
    
            // Once the application has booted we will also fire some "booted" callbacks
            // for any listeners that need to do work after this initial booting gets
            // finished. This is useful when ordering the boot-up processes we run.
            $this->fireAppCallbacks($this->bootingCallbacks);
    
            array_walk($this->serviceProviders, function ($p) {
                $this->bootProvider($p);
            });
    
            $this->booted = true;
    
            $this->fireAppCallbacks($this->bootedCallbacks);
        }
    
        /**
         * Boot the given service provider.
         *
         * @param  IlluminateSupportServiceProvider  $provider
         * @return mixed
         */
        protected function bootProvider(ServiceProvider $provider)
        {
            if (method_exists($provider, 'boot')) {
                return $this->call([$provider, 'boot']);
            }
        }
    
        /**
         * Register a new boot listener.
         *
         * @param  callable  $callback
         * @return void
         */
        public function booting($callback)
        {
            $this->bootingCallbacks[] = $callback;
        }
    
        /**
         * Register a new "booted" listener.
         *
         * @param  callable  $callback
         * @return void
         */
        public function booted($callback)
        {
            $this->bootedCallbacks[] = $callback;
    
            if ($this->isBooted()) {
                $this->fireAppCallbacks([$callback]);
            }
        }
    
        /**
         * Call the booting callbacks for the application.
         *
         * @param  callable[]  $callbacks
         * @return void
         */
        protected function fireAppCallbacks(array $callbacks)
        {
            foreach ($callbacks as $callback) {
                $callback($this);
            }
        }
    
        /**
         * {@inheritdoc}
         */
        public function handle(SymfonyRequest $request, $type = self::MASTER_REQUEST, $catch = true)
        {
            return $this[HttpKernelContract::class]->handle(Request::createFromBase($request));
        }
    
        /**
         * Determine if middleware has been disabled for the application.
         *
         * @return bool
         */
        public function shouldSkipMiddleware()
        {
            return $this->bound('middleware.disable') &&
                   $this->make('middleware.disable') === true;
        }
    
        /**
         * Get the path to the cached services.php file.
         *
         * @return string
         */
        public function getCachedServicesPath()
        {
            return $this->normalizeCachePath('APP_SERVICES_CACHE', 'cache/services.php');
        }
    
        /**
         * Get the path to the cached packages.php file.
         *
         * @return string
         */
        public function getCachedPackagesPath()
        {
            return $this->normalizeCachePath('APP_PACKAGES_CACHE', 'cache/packages.php');
        }
    
        /**
         * Determine if the application configuration is cached.
         *
         * @return bool
         */
        public function configurationIsCached()
        {
            return file_exists($this->getCachedConfigPath());
        }
    
        /**
         * Get the path to the configuration cache file.
         *
         * @return string
         */
        public function getCachedConfigPath()
        {
            return $this->normalizeCachePath('APP_CONFIG_CACHE', 'cache/config.php');
        }
    
        /**
         * Determine if the application routes are cached.
         *
         * @return bool
         */
        public function routesAreCached()
        {
            return $this['files']->exists($this->getCachedRoutesPath());
        }
    
        /**
         * Get the path to the routes cache file.
         *
         * @return string
         */
        public function getCachedRoutesPath()
        {
            return $this->normalizeCachePath('APP_ROUTES_CACHE', 'cache/routes.php');
        }
    
        /**
         * Determine if the application events are cached.
         *
         * @return bool
         */
        public function eventsAreCached()
        {
            return $this['files']->exists($this->getCachedEventsPath());
        }
    
        /**
         * Get the path to the events cache file.
         *
         * @return string
         */
        public function getCachedEventsPath()
        {
            return $this->normalizeCachePath('APP_EVENTS_CACHE', 'cache/events.php');
        }
    
        /**
         * Normalize a relative or absolute path to a cache file.
         *
         * @param  string  $key
         * @param  string  $default
         * @return string
         */
        protected function normalizeCachePath($key, $default)
        {
            if (is_null($env = Env::get($key))) {
                return $this->bootstrapPath($default);
            }
    
            return Str::startsWith($env, '/')
                    ? $env
                    : $this->basePath($env);
        }
    
        /**
         * Determine if the application is currently down for maintenance.
         *
         * @return bool
         */
        public function isDownForMaintenance()
        {
            return file_exists($this->storagePath().'/framework/down');
        }
    
        /**
         * Throw an HttpException with the given data.
         *
         * @param  int  $code
         * @param  string  $message
         * @param  array  $headers
         * @return void
         *
         * @throws SymfonyComponentHttpKernelExceptionHttpException
         * @throws SymfonyComponentHttpKernelExceptionNotFoundHttpException
         */
        public function abort($code, $message = '', array $headers = [])
        {
            if ($code == 404) {
                throw new NotFoundHttpException($message);
            }
    
            throw new HttpException($code, $message, null, $headers);
        }
    
        /**
         * Register a terminating callback with the application.
         *
         * @param  callable|string  $callback
         * @return $this
         */
        public function terminating($callback)
        {
            $this->terminatingCallbacks[] = $callback;
    
            return $this;
        }
    
        /**
         * Terminate the application.
         *
         * @return void
         */
        public function terminate()
        {
            foreach ($this->terminatingCallbacks as $terminating) {
                $this->call($terminating);
            }
        }
    
        /**
         * Get the service providers that have been loaded.
         *
         * @return array
         */
        public function getLoadedProviders()
        {
            return $this->loadedProviders;
        }
    
        /**
         * Get the application's deferred services.
         *
         * @return array
         */
        public function getDeferredServices()
        {
            return $this->deferredServices;
        }
    
        /**
         * Set the application's deferred services.
         *
         * @param  array  $services
         * @return void
         */
        public function setDeferredServices(array $services)
        {
            $this->deferredServices = $services;
        }
    
        /**
         * Add an array of services to the application's deferred services.
         *
         * @param  array  $services
         * @return void
         */
        public function addDeferredServices(array $services)
        {
            $this->deferredServices = array_merge($this->deferredServices, $services);
        }
    
        /**
         * Determine if the given service is a deferred service.
         *
         * @param  string  $service
         * @return bool
         */
        public function isDeferredService($service)
        {
            return isset($this->deferredServices[$service]);
        }
    
        /**
         * Configure the real-time facade namespace.
         *
         * @param  string  $namespace
         * @return void
         */
        public function provideFacades($namespace)
        {
            AliasLoader::setFacadeNamespace($namespace);
        }
    
        /**
         * Get the current application locale.
         *
         * @return string
         */
        public function getLocale()
        {
            return $this['config']->get('app.locale');
        }
    
        /**
         * Set the current application locale.
         *
         * @param  string  $locale
         * @return void
         */
        public function setLocale($locale)
        {
            $this['config']->set('app.locale', $locale);
    
            $this['translator']->setLocale($locale);
    
            $this['events']->dispatch(new LocaleUpdated($locale));
        }
    
        /**
         * Determine if application locale is the given locale.
         *
         * @param  string  $locale
         * @return bool
         */
        public function isLocale($locale)
        {
            return $this->getLocale() == $locale;
        }
    
        /**
         * Register the core class aliases in the container.
         *
         * @return void
         */
        public function registerCoreContainerAliases()
        {
            foreach ([
                'app'                  => [self::class, IlluminateContractsContainerContainer::class, IlluminateContractsFoundationApplication::class, PsrContainerContainerInterface::class],
                'auth'                 => [IlluminateAuthAuthManager::class, IlluminateContractsAuthFactory::class],
                'auth.driver'          => [IlluminateContractsAuthGuard::class],
                'blade.compiler'       => [IlluminateViewCompilersBladeCompiler::class],
                'cache'                => [IlluminateCacheCacheManager::class, IlluminateContractsCacheFactory::class],
                'cache.store'          => [IlluminateCacheRepository::class, IlluminateContractsCacheRepository::class, PsrSimpleCacheCacheInterface::class],
                'cache.psr6'           => [SymfonyComponentCacheAdapterPsr16Adapter::class, SymfonyComponentCacheAdapterAdapterInterface::class, PsrCacheCacheItemPoolInterface::class],
                'config'               => [IlluminateConfigRepository::class, IlluminateContractsConfigRepository::class],
                'cookie'               => [IlluminateCookieCookieJar::class, IlluminateContractsCookieFactory::class, IlluminateContractsCookieQueueingFactory::class],
                'encrypter'            => [IlluminateEncryptionEncrypter::class, IlluminateContractsEncryptionEncrypter::class],
                'db'                   => [IlluminateDatabaseDatabaseManager::class, IlluminateDatabaseConnectionResolverInterface::class],
                'db.connection'        => [IlluminateDatabaseConnection::class, IlluminateDatabaseConnectionInterface::class],
                'events'               => [IlluminateEventsDispatcher::class, IlluminateContractsEventsDispatcher::class],
                'files'                => [IlluminateFilesystemFilesystem::class],
                'filesystem'           => [IlluminateFilesystemFilesystemManager::class, IlluminateContractsFilesystemFactory::class],
                'filesystem.disk'      => [IlluminateContractsFilesystemFilesystem::class],
                'filesystem.cloud'     => [IlluminateContractsFilesystemCloud::class],
                'hash'                 => [IlluminateHashingHashManager::class],
                'hash.driver'          => [IlluminateContractsHashingHasher::class],
                'translator'           => [IlluminateTranslationTranslator::class, IlluminateContractsTranslationTranslator::class],
                'log'                  => [IlluminateLogLogManager::class, PsrLogLoggerInterface::class],
                'mailer'               => [IlluminateMailMailer::class, IlluminateContractsMailMailer::class, IlluminateContractsMailMailQueue::class],
                'auth.password'        => [IlluminateAuthPasswordsPasswordBrokerManager::class, IlluminateContractsAuthPasswordBrokerFactory::class],
                'auth.password.broker' => [IlluminateAuthPasswordsPasswordBroker::class, IlluminateContractsAuthPasswordBroker::class],
                'queue'                => [IlluminateQueueQueueManager::class, IlluminateContractsQueueFactory::class, IlluminateContractsQueueMonitor::class],
                'queue.connection'     => [IlluminateContractsQueueQueue::class],
                'queue.failer'         => [IlluminateQueueFailedFailedJobProviderInterface::class],
                'redirect'             => [IlluminateRoutingRedirector::class],
                'redis'                => [IlluminateRedisRedisManager::class, IlluminateContractsRedisFactory::class],
                'redis.connection'     => [IlluminateRedisConnectionsConnection::class, IlluminateContractsRedisConnection::class],
                'request'              => [IlluminateHttpRequest::class, SymfonyComponentHttpFoundationRequest::class],
                'router'               => [IlluminateRoutingRouter::class, IlluminateContractsRoutingRegistrar::class, IlluminateContractsRoutingBindingRegistrar::class],
                'session'              => [IlluminateSessionSessionManager::class],
                'session.store'        => [IlluminateSessionStore::class, IlluminateContractsSessionSession::class],
                'url'                  => [IlluminateRoutingUrlGenerator::class, IlluminateContractsRoutingUrlGenerator::class],
                'validator'            => [IlluminateValidationFactory::class, IlluminateContractsValidationFactory::class],
                'view'                 => [IlluminateViewFactory::class, IlluminateContractsViewFactory::class],
            ] as $key => $aliases) {
                foreach ($aliases as $alias) {
                    $this->alias($key, $alias);
                }
            }
        }
    
        /**
         * Flush the container of all bindings and resolved instances.
         *
         * @return void
         */
        public function flush()
        {
            parent::flush();
    
            $this->buildStack = [];
            $this->loadedProviders = [];
            $this->bootedCallbacks = [];
            $this->bootingCallbacks = [];
            $this->deferredServices = [];
            $this->reboundCallbacks = [];
            $this->serviceProviders = [];
            $this->resolvingCallbacks = [];
            $this->terminatingCallbacks = [];
            $this->afterResolvingCallbacks = [];
            $this->globalResolvingCallbacks = [];
        }
    
        /**
         * Get the application namespace.
         *
         * @return string
         *
         * @throws RuntimeException
         */
        public function getNamespace()
        {
            if (! is_null($this->namespace)) {
                return $this->namespace;
            }
    
            $composer = json_decode(file_get_contents($this->basePath('composer.json')), true);
    
            foreach ((array) data_get($composer, 'autoload.psr-4') as $namespace => $path) {
                foreach ((array) $path as $pathChoice) {
                    if (realpath($this->path()) === realpath($this->basePath($pathChoice))) {
                        return $this->namespace = $namespace;
                    }
                }
            }
    
            throw new RuntimeException('Unable to detect application namespace.');
        }
    }
    PHP
     
     

    2.2.2 打印信息

    $this->line("<info>Laravel development server started:</info> http://{$this->host()}:{$this->port()}");
    PHP
     

    2.2.3 执行命令

    执行命令是通过 passthru($this->serverCommand()) 的原生函数 passthru() 来实现的,其中 $this->serverCommand() 负责返回一个可以执行的字符串命令,具体代码就在同文件的 serverCommand() 中:

    passthru($this->serverCommand(), $status);
    PHP
    /**     * 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'))        );    }
    PHP

    sprintf() 的四个字符串占位符会被后面传入的四个参数替换,最终打印出一个可以执行的 PHP 命令,其中这四个分别对应的是:

    //php 的可执行全路径ProcessUtils::escapeArgument((new PhpExecutableFinder)->find(false))
    
    //host ,默认为 127.0.0.1$this->host()
    
    //port ,默认为 8000$this->port()
    
    //执行代码的全路径ProcessUtils::escapeArgument(base_path('server.php'))
    

    所以,最后 serverCommand() 返回的是什么呢?我们可以直接打印看下:

     

    打印的结果:

     

    所以我们可以得出,php artisan serve 命令就是直接使用 php 执行 server.php 文件,这个文件就在项目的根目录下,比如就是相当于我们直接在命令行执行下面这个命令:

    php -S 127.0.0.1:8001 server.php
    
     

    2.2.4 最后

    php artisan serve 命令背后其实也就是使用了 php 去直接执行文件,跟我们在使用php -S 127.0.0.1:8001 PHP 的内置服务器没有太大的区别。

    三、php artisan serve文档

    通过使用php artisan help serve进行文档查看

     
    php artisan help serveDescription:  Serve the application on the PHP development serverUsage:  serve [options]Options:      --host[=HOST]     The host address to serve the application on [default: "127.0.0.1"]      --port[=PORT]     The port to serve the application on      --tries[=TRIES]   The max number of ports to attempt to serve from [default: 10]  -h, --help            Display this help message  -q, --quiet           Do not output any message  -V, --version         Display this application version      --ansi            Force ANSI output      --no-ansi         Disable ANSI output  -n, --no-interaction  Do not ask any interactive question      --env[=ENV]       The environment the command should run under  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
    

     

  • 相关阅读:
    AIX系统/var/adm/wtmp大文件处理
    script & scriptreplay
    Ubuntu/Debianpxe/isopreseed
    Ubuntu12.04安装gimp-2.8
    Ubuntu 3D特效一览
    Unix history图览
    Undelete Files on Linux Systems
    开源界有趣的循环缩写和LOGO
    Ubuntu上的dock
    linux下歌曲、视频、文件等乱码
  • 原文地址:https://www.cnblogs.com/joshua317/p/15500817.html
Copyright © 2011-2022 走看看