Lumen开发:lumen源码解读之初始化(1)——app实例

先来看看入口文件public/index.php

//请求头
header('Content-Type: application/json; charset=utf-8');
 
/*
 |--------------------------------------------------------------------------
 | Create The Application(创建应用程序)
 |--------------------------------------------------------------------------
 | 首先我们需要一个应用实例。
 | 这将创建一个应用程序的实例/容器和应用程序准备好接收HTTP /控制台从环境要求。
 */
$app = require __DIR__.'/../bootstrap/app.php';
 
/*
 |--------------------------------------------------------------------------
 | Run The Application (运行应用程序)
 |--------------------------------------------------------------------------
 | 一旦我们有了应用程序,
 | 我们就可以通过内核处理传入的请求,并将相关的响应发送回客户机的浏览器,
 | 让他们享受我们为他们准备的创造性和奇妙的应用程序。
 */
$app->run();

那么现在最重要的就是bootstrap/app.php了

require_once __DIR__ . '/../vendor/autoload.php';
 
try {
    (new Dotenv\Dotenv(__DIR__ . '/../'))->load();
} catch (Dotenv\Exception\InvalidPathException $e) {
    //
}

这里是引入Composer的包,之前讲过,这里不详谈。Dotenv是env配置的使用。

/*
|--------------------------------------------------------------------------
| Create The Application(创建应用程序)
|--------------------------------------------------------------------------
|
| 在这里,我们将加载环境并创建作为该框架的中心部分的应用程序实例。
| 我们将使用这个应用程序作为这个框架的“IOC”容器和路由器。
|
*/
 
$app = new Laravel\Lumen\Application(
    realpath(__DIR__ . '/../')
);
 
$app->withFacades();
 
$app->withEloquent();
Laravel\Lumen\Application

class Application extends Container
{
    use Concerns\RoutesRequests,
        Concerns\RegistersExceptionHandlers;
。
。
。

/**
  * Create a new Lumen application instance.(创建一个新的Lumen应用程序实例。)
  */
public function __construct($basePath = null)
{
    if (! empty(env('APP_TIMEZONE'))) {
        date_default_timezone_set(env('APP_TIMEZONE', 'UTC'));
    }
 
    $this->basePath = $basePath;
 
    $this->bootstrapContainer();
    $this->registerErrorHandling();
}

这个可以说是整个Lumen应用程序最最核心的类了,上继承了核心容器类(Container),左右引用了Concerns\RoutesRequests(路由),Concerns\RegistersExceptionHandlers(异常处理),下又实例了app对象,很是重要喔!!!$this->bootstrapContainer();

/**
 * Bootstrap the application container.(引导应用程序容器)
 *
 * @return void
 */
protected function bootstrapContainer()
{
    static::setInstance($this);
 
    $this->instance('app', $this);
    $this->instance('Laravel\Lumen\Application', $this);
 
    $this->instance('path', $this->path());
 
    $this->registerContainerAliases();
}

Lumen的依赖注入服务主要都是在容器(Container)中进行,所以说这个步骤很重要,

先看看setInstance()函数

/**
 * Set the shared instance of the container.(设置容器的共享实例。)
 *
 * @param  \Illuminate\Contracts\Container\Container|null  $container
 * @return static
 */
public static function setInstance(ContainerContract $container = null)
{
    return static::$instance = $container;
}

简单一句话,把当前继承Container,实现ContainerContract接口的Application的app实例,注册到Container的$instance对象中,感觉这样就实现了相互之间的贯穿,后面会有大用!

然后就到了$this->instance()函数了,

/**
   * Register an existing instance as shared in the container.(登记一个现有的实例所共享的容器。)
   */
  public function instance($abstract, $instance)
  {
      $this->removeAbstractAlias($abstract);//从上下文绑定缓存中删除一个别名。
 
      unset($this->aliases[$abstract]);//删除对应注册类型别名。
 
       //检查以确定此类型是否已被绑定,
      //如果有我们将触发与容器注册的回调和反射可以消费类已经解决这里的更新。
      $this->instances[$abstract] = $instance;

        if ($this->bound($abstract)) {  //确定给定的类型已被绑定。
            $this->rebound($abstract);
        }
  }
	//从上下文绑定缓存中删除一个别名。
    protected function removeAbstractAlias($searched)
    {
        if (! isset($this->aliases[$searched])) {
            return;
        }

        foreach ($this->abstractAliases as $abstract => $aliases) {
            foreach ($aliases as $index => $alias) {
                if ($alias == $searched) {
                    unset($this->abstractAliases[$abstract][$index]);
                }
            }
        }
    }
 	//确定给定的类型已被绑定。
    public function bound($abstract)
    {   
        return isset($this->bindings[$abstract]) ||
               isset($this->instances[$abstract]) ||
               $this->isAlias($abstract);
    }

再到$this->registerContainerAliases()函数,这个函数用于注释核心容器的别名

protected function registerContainerAliases()
    {
        $this->aliases = [
            'Illuminate\Contracts\Foundation\Application' => 'app',
            'Illuminate\Contracts\Auth\Factory' => 'auth',
            'Illuminate\Contracts\Auth\Guard' => 'auth.driver',
            'Illuminate\Contracts\Cache\Factory' => 'cache',
            'Illuminate\Contracts\Cache\Repository' => 'cache.store',
            'Illuminate\Contracts\Config\Repository' => 'config',
            'Illuminate\Container\Container' => 'app',
            'Illuminate\Contracts\Container\Container' => 'app',
            'Illuminate\Database\ConnectionResolverInterface' => 'db',
            'Illuminate\Database\DatabaseManager' => 'db',
            'Illuminate\Contracts\Encryption\Encrypter' => 'encrypter',
            'Illuminate\Contracts\Events\Dispatcher' => 'events',
            'Illuminate\Contracts\Hashing\Hasher' => 'hash',
            'log' => 'Psr\Log\LoggerInterface',
            'Illuminate\Contracts\Queue\Factory' => 'queue',
            'Illuminate\Contracts\Queue\Queue' => 'queue.connection',
            'request' => 'Illuminate\Http\Request',
            'Laravel\Lumen\Routing\UrlGenerator' => 'url',
            'Illuminate\Contracts\Validation\Factory' => 'validator',
            'Illuminate\Contracts\View\Factory' => 'view',
        ];
    }

有木有对这些名称很熟悉的感觉!

至此$this->bootstrapContainer()就执行完了,再来看看$this->registerErrorHandling(),既然是异常处理,肯定是在Laravel\Lumen\Concerns\RegistersExceptionHandlers(异常处理)里了

/**
 * Set the error handling for the application.(设置应用程序的错误处理。)
 *
 * @return void
 */
protected function registerErrorHandling()
{
    error_reporting(-1);
 
    set_error_handler(function ($level, $message, $file = '', $line = 0) {
        if (error_reporting() & $level) {
            throw new ErrorException($message, 0, $level, $file, $line);
        }
    });
 
    set_exception_handler(function ($e) {
        $this->handleUncaughtException($e);
    });
 
    register_shutdown_function(function () {
        $this->handleShutdown();
    });
}

到这里,$app应用程序就初始好了,下一篇会接着讲

$app->withFacades();//为应用程序注册门面。
 
$app->withEloquent();//为应用程序加载功能强大的库。

和后面的内容!!!

猜你喜欢

转载自blog.csdn.net/qq_26249609/article/details/84346011
今日推荐