系统架构

来自tomtalk
Tom讨论 | 贡献2016年9月18日 (日) 04:01的版本 (创建页面,内容为“==请求生命周期== <source lang='php'> require __DIR__.'/../bootstrap/autoload.php'; $app = require_once __DIR__.'/../bootstrap/app.php'; //创建服务容器...”)

(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳转至: 导航搜索

请求生命周期

require __DIR__.'/../bootstrap/autoload.php';
 
$app = require_once __DIR__.'/../bootstrap/app.php';  //创建服务容器
 
/**
 * 创建http核心(或者终端核心)。
 * config/app.php 
 * 1、注册服务提供者
 * 2、boot()
 * 3、注册中间件
 */
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); 
 
/**
 * 1、路由分派
 * 2、执行路由中间件
 * 3、跳转到控制器
 */
$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);
 
$response->send();
 
$kernel->terminate($request, $response);

应用程序结构

服务提供者

服务提供者是所有Laravel应用程序启动的中心所在。包括你自己的应用程序,以及所有的Laravel核心服务,都是通过服务提供者启动的。

若你打开Laravel的config/app.php文件,你将会看到providers数组。这些都是你的应用程序会加载到的所有服务提供者类。当然,它们之中有很多属于「延迟」提供者,意味着除非真正需要它们所提供的服务,否则它们并不会在每一个请求中都被加载。


注册方法

如同之前提到的,在register方法中,你应该只将事物绑定至服务容器中。永远不要尝试在register方法中注册任何事件侦听器、路由或任何其它功能。否则的话,你可能会意外地使用到由尚未加载的服务提供者所提供的服务。


延迟提供者

若你的提供者仅在服务容器中注册绑定,你可以选择延缓其注册,直到真正需要其中已注册的绑定,延迟提供者加载可提高应用程序的性能。

要延迟提供者加载,可将defer属性设置为true,并定义一个provides方法。provides方法会返回提供者所注册的服务容器绑定。

服务容器

在服务提供者中,你总是可以通过$this->app实例变量访问容器。


绑定
  1. 绑定一个单例
  2. 绑定实例
  3. 绑定接口至实现
  4. 情境绑定
  5. 标记


解析

有几种方式可以从容器中解析一些东西。

$fooBar = $this->app->make('FooBar');

或者,你可以像数组一样从容器中进行访问,因为他实现了PHP的ArrayAccess接口:

$fooBar = $this->app['FooBar'];


容器事件

每当服务容器解析一个对象时就会触发事件。你可以使用resolving方法监听这个事件。

Facades

Facades为应用程序的服务容器中可用的类提供了一个「静态」接口。Laravel本身附带许多的facades,甚至你可能在不知情的状况下已经在使用他们!Laravel「facades」作为在服务容器内基类的「静态代理」,拥有简洁、易表达的语法优点,同时维持着比传统静态方法更高的可测试性和灵活性。

$user = Cache::get('user:'.$id);

如果我们查看Illuminate\Support\Facades\Cache类,你会发现没有静态方法get。

相反的,Cache facade继承了基底Facade类以及定义了getFacadeAccessor()方法。记住,这个方法的工作是返回服务容器绑定的名称。当用户在Cache facade上参考任何的静态方法,Laravel会从服务容器解析被绑定的cache以及针对对象运行请求的方法(在这个例子中是get)。

Contracts

Laravel的Contracts是一组定义了框架核心服务的接口(php class interfaces)。例如:

  • Illuminate\Contracts\Queue\Queue contract 定义了队列任务所需要的方法
  • Illuminate\Contracts\Mail\Mailer contract 定义了寄送e-mail需要的方法

框架对于每个contract都有提供对应的实现。


Contracts Vs. Facades

Laravel的facades提供一个简单的方法来使用服务,而不需要使用类型提示和在服务容器之外解析contracts。然而,使用contracts可以明显地定义出类的依赖,对大部分应用进程而言,使用facade就足够了,然而,若你实在需要特别的低耦合,使用contracts可以做到这一点。


简单性

当所有的Laravel服务都使用简洁的接口定义,就能够很容易决定一个服务需要提供的功能。可以将contracts视为说明框架特色的简洁文档。

除此之外,当依赖的接口足够简洁时,代码的可读性和可维护性大大提高。比起搜索一个大型复杂的类里有哪些可用的方法,你有一个简单,干净的接口可以参考。