美文网首页
【再读lara】生命周期 ~ 请求实例化

【再读lara】生命周期 ~ 请求实例化

作者: 邱杉的博客 | 来源:发表于2018-01-02 18:41 被阅读0次

    public\index.php

    $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
    
    $response = $kernel->handle(
        $request = Illuminate\Http\Request::capture()
    );
    
    $response->send();
    
    $kernel->terminate($request, $response);
    

    Illuminate\Http\Request.php

    //通过服务器提供的变量创建一个HTTP请求实例
    public static function capture()
    {
        static::enableHttpMethodParameterOverride();
        return static::createFromBase(SymfonyRequest::createFromGlobals());
    } 
    //创建一个请求实例通过Symfony实例
    public static function createFromBase(SymfonyRequest $request)
    {
        if ($request instanceof static) {
            return $request;
        }
        $content = $request->content;
        $request = (new static)->duplicate(
            $request->query->all(), $request->request->all(), $request->attributes->all(),
            $request->cookies->all(), $request->files->all(), $request->server->all()
        );
        $request->content = $content;
        $request->request = $request->getInputSource();
    
        return $request;
    }
    

    处理请求

    Illuminate\Foundation\Http\Kernel.php

    //处理一个输入HTTP请求
    public function handle($request)
    {
        try {
            $request->enableHttpMethodParameterOverride();
            $response = $this->sendRequestThroughRouter($request);
    } 
    //省略异常处理部分代码
    $this->app['events']->fire('kernel.handled', [$request, $response]);
         return $response;
    }
    
    
    protected $bootstrappers = [
            'Illuminate\Foundation\Bootstrap\DetectEnvironment',
            'Illuminate\Foundation\Bootstrap\LoadConfiguration',
            'Illuminate\Foundation\Bootstrap\ConfigureLogging',
            'Illuminate\Foundation\Bootstrap\HandleExceptions',
            'Illuminate\Foundation\Bootstrap\RegisterFacades',
            'Illuminate\Foundation\Bootstrap\RegisterProviders',
            'Illuminate\Foundation\Bootstrap\BootProviders',
        ];
    //将请求通过中间件和路由处理
    protected function sendRequestThroughRouter($request)
    {
        $this->app->instance('request', $request);
        Facade::clearResolvedInstance('request');
        $this->bootstrap();
        return (new Pipeline($this->app))
                    ->send($request)
                    ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
                    ->then($this->dispatchToRouter());
    }
    
    }
    //针对请求为应用程序“拔靴带”    
    public function bootstrap()
    {
        if (! $this->app->hasBeenBootstrapped()) {
            $this->app->bootstrapWith($this->bootstrappers());
        }
    }
    
    

    Illuminate\Foundation\Application.php

    //执行bootstrap类的数组
    public function bootstrapWith(array $bootstrappers)
    {
        $this->hasBeenBootstrapped = true;
        foreach ($bootstrappers as $bootstrapper) {
            $this['events']->fire('bootstrapping: '.$bootstrapper, [$this]);
            $this->make($bootstrapper)->bootstrap($this);
            $this['events']->fire('bootstrapped: '.$bootstrapper, [$this]);
        }
    }
    

    Illuminate\Foundation\Bootstrap\RegisterFacades.php

     public function bootstrap(Application $app)
     {
            Facade::clearResolvedInstances();
            Facade::setFacadeApplication($app);
          AliasLoader::getInstance($app->make('config')->get('app.aliases'))->register();
    }
    

    Illuminate\Foundation\AliasLoader.php

    //创建一个别名加载的实例对象
     public static function getInstance(array $aliases = [])
    {
            if (is_null(static::$instance)) {
                return static::$instance = new static($aliases);
            }
            $aliases = array_merge(static::$instance->getAliases(), $aliases);
            static::$instance->setAliases($aliases);
            return static::$instance;
    }
    
    
    //在自动加载栈中注册一个自动加载函数
    public function register()
    {
            if (!$this->registered) {
                $this->prependToLoaderStack();
                $this->registered = true;
            }
      }
      //将这个加载函数加到自动加载栈的开始处
      protected function prependToLoaderStack()
      {
            spl_autoload_register([$this, 'load'], true, true);
      }
      //加载一个类的别名  
      public function load($alias)
     {
            if (isset($this->aliases[$alias])) {
                return class_alias($this->aliases[$alias], $alias);
            }
    }
    

    Illuminate\Routing\Router类的实例,即通过“static::$app[$name]”实现,最终将会调用这个Router类实例中的get()方法。绕了一圈,终于绕出来了,现在明白注册外观的真正用途了吧,后面的如Request::input()等都是通过外观别名完成最终函数调用的。

    对于别名Laravel框架中有两个,一个是容器核心别名,定义在Application类中,而存储在Application类实例的$aliases属性中(实际上该属性是在Container类中,因为Application类继承Container类,所以继承了这个属性,这里没有给出加上命名空间的全部名称);另一个是外观别名,定义在app.php配置文件中,程序运行后存储在AliasLoader类实例的$aliases属性中。

    Illuminate\Support\Facades\Facade.php

    服务提供者注册

    Illuminate\Foundation\Bootstrap\RegisterProviders.php

    //服务提供者注册   
    public function bootstrap(Application $app)
    {
            $app->registerConfiguredProviders();
    }
    

    Illuminate\Foundation\Application.php

    //注册所有配置的服务提供者
     public function registerConfiguredProviders()
    {
            $manifestPath = $this->getCachedServicesPath();
            (new ProviderRepository($this, new Filesystem, $manifestPath))
                        ->load($this->config['app.providers']);
    }
    

    when类是注册事件,只有当事件发生时才会自动注册这个服务提供者;
    eager类会直接加载,加载方式和注册基础服务提供者的过程相同;
    deferred类的服务提供者存储在列表中,需要加载时才会加载。

    Illuminate\Foundation\ProviderRepository.php

      //注册应用的服务提供者
      public function load(array $providers)
    {
            //加载larave\bootstrap\cache\services.json文件中的服务提供者
       $manifest = $this->loadManifest();
            //加载服务清单, 这里包含程序所有的服务提供者并进行了分类
            if ($this->shouldRecompile($manifest, $providers)) {
                $manifest = $this->compileManifest($providers);
            }
    
            //服务提供者加载事件, 当这个事件发生时才自动加载这个服务提供者
            foreach ($manifest['when'] as $provider => $events) {
                $this->registerLoadEvents($provider, $events);
            }
           //提前注册那些必须加载的服务提供者, 以此为应用提供服务
            foreach ($manifest['eager'] as $provider) {
                $this->app->register($this->createProvider($provider));
            }
            //在列表中记录延迟加载的服务提供者, 需要时再加载
            $this->app->setDeferredServices($manifest['deferred']);
        }
    

    启动服务

    Illuminate\Foundation\Bootstrap\BootProviders.php

     public function bootstrap(Application $app)
    {
            $app->boot();
    }
    

    Illuminate\Foundation\Application.php

    //启动应用程序的服务提供者  
    public function boot()
    {
            if ($this->booted) {
                return;
            }
            $this->fireAppCallbacks($this->bootingCallbacks);
            array_walk($this->serviceProviders, function ($p) {
                $this->bootProvider($p);
            });
            $this->booted = true;
            $this->fireAppCallbacks($this->bootedCallbacks);
     }
    
    //启动给定的服务提供者
     protected function bootProvider(ServiceProvider $provider)
     {
            if (method_exists($provider, 'boot')) {
                return $this->call([$provider, 'boot']);
            }
    }
    

    相关文章

      网友评论

          本文标题:【再读lara】生命周期 ~ 请求实例化

          本文链接:https://www.haomeiwen.com/subject/dwyqnxtx.html