Laravel 之 Application---实践篇

作为容器使用方法

在《Application理论篇》中介绍过,它作为容器提供了两个主要的功能:

  • 注册创建对象的规则,并在需要的时候创建它;
  • 提供了类似全局变量存储数据的能力。

它的基本使用步骤是:

  • 向容器注册生成对象的规则
  • 从容器里面获取对象

注册构建对象的规则

有两种方式向容器注册生成对象的规则

  • 指定要类的地址,这种方式有问题问题,如果类的构造函数的参数是基本数据类型的话,容器无法注入这部分数据,会发导致创建失败
  • 指定一个闭包函数,具体创建类的逻辑,可以在闭包函数中定义,最终只需要返回创建的对象。ServiceProvider中被大量使用。

    
    class Car{
    
     protected $name;
     public function __construct(\Illuminate\Foundation\Application $app, $name)
     {
         $this->name = $name;
         // $app
     }
    
     function __toString()
     {
        return (string)$this->name;
     }
    
    }
    
    class Something{
    
    }
    
    $app = new \Illuminate\Foundation\Application();
    
    // 使用闭包定义创建对象的规则
    $app->bind('car',function()use($app){
     return new Car($app,'雷克萨斯');
    });
    
    // 使用类名的方式
    $app->bind('something',Something::class);
    

    共享对象

    有些时候,我们在希望在应用程序运行的过程中,对象只被创建一次。

    class Car{
    
     protected $name;
     public function __construct(\Illuminate\Foundation\Application $app, $name)
     {
         $this->name = $name;
         // $app
     }
    
     function __toString()
     {
        return (string)$this->name;
     }
    
    }
    
    class Something{
    
    }
    
    $app = new \Illuminate\Foundation\Application();
    
    // 使用闭包定义创建对象的规则
    $app->bind('car',function()use($app){
     return new Car($app,'雷克萨斯'.mt_rand(1,100));
    });
    
    $app->singleton('car_singleton',function()use($app){
     return new Car($app,'雷克萨斯'.mt_rand(1,100));
    });
    
    $range = range(1,5);
    echo "===============car================\r\n";
    foreach ($range as $v){
     echo $app->make('car')."\r\n";//每次都会创建新的对象
    }
    
    echo "===============car_singleton================\r\n";
    foreach ($range as $v){
     echo $app->make('car_singleton')."\r\n";//对象永远只有一个
    }
    

    存储数据

一般而言,在应用程序运行的生命周期中,只会存在一个对象。所以可以把全局性质的数据交由它统一保管。


$app = new \Illuminate\Foundation\Application();
$app->instance('data',[1,2,3]);//数据存入容器中
$data = $app->make('data');// 获取容器中存储的数据

提供了应用程序运行需要的基本功能

注册基础的服务

先有鸡还是先有蛋是未解之谜。但是在larval的Application中,它是最先被创建的对象,它自身执行了一些基础服务的构建。

具体包括

  • 把Application对象自身放入容器中。 $this->instance('app', $this);
  • 注册EventServiceProvider服务,事件(events)系统是laravel根基。
  • 注册LogServiceProvider服务,作为一个成熟的系统,日志(log)必不可少。
  • 注册RoutingServiceProvider系列服务,请求被转发给具体的处理控制器的规则,就是由这系列服务控制的。

    提供注册和执行ServerProdiver的功能

    ServerProdiver(服务提供者)有下面几个特征:

    • 构造函数有一个Application类型的参数,通常被被保存在它的属性里面
    • 必须有一个register方法,这个方法通常的作用是向容器里面注册一个类构建规则或者一个值
    • 可以有一个boot方法,用来执行一些初始化操作

    在laravel中所有的独立的功能模块都是以 ServerProdiver为单位,注入到容器里面的。

    提供了设置和获取项目基本信息的接口

    项目相关的路径信息都被注入到了容器中

    
    $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());
    
    // 使用
    
    $configPath = app('path.config');// 获取项目的配置文件所在目录
    // .................
    

    自定义扩展功能

    在laravel中,组件内部的一些状态都是通过事件的形式曝露出来的。例如在执行引导器(bootstraper)的时候

    
     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]);
         }
     }
    

    另外一些操作是通过类似hook的方式进行的,例如

    afterLoadingEnvironment(Closure $callback) 加载完环境变量后执行的操作

    无论是通过event的方式还是通过hook的方式进行扩展,本质上都是向组件注册一个回掉函数,组件在合适的时机执行这个回掉函数。

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!