您的位置:首页 > 编程语言 > PHP开发

分析,理解,优化Laravel

2016-04-19 00:00 337 查看
摘要: 使用Laravel接近两年了, 从4.2到现在的5.2。大多数情况下,Laravel都能很好的支撑我们的系统。不管你是否使用或打算使用, 了解Laravel的设计对于提高程序水平也很有帮助。

分析,理解,优化Laravel

#前言
使用Laravel接近两年了, 从4.2到现在的5.2。大多数情况下,Laravel都能很好的支撑我们的系统。不管你是否使用或打算使用, 了解Laravel的设计对于提高程序水平也很有帮助。本文是我的一个学习laravel的过程, 也是我实现高性能server stone下一个目标的过程。限于本人水平有限,错误在所难免,希望大家不吝指正。

注:因为是边写边改, 所以内容目录随时会有调整。

#一个HTTP请求的执行流程

创建app, app本质上是一个ioc容器(Illuminate\Container\Container),这个概念对于laravel很重要,laravel的核心组件都会注册到这个容器里面。

$app = new Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
);


初始化全局ioc容器app, 并把自己本身注册进去

注册基本的Service Provider: EventServiceProvider, RoutingServiceProvider

注册核心的class别名,参看:registerCoreContainerAliases

核心接口绑定, 如果需替换自己实现的Kernel, 可以修改这里。

// http处理
$app->singleton(
Illuminate\Contracts\Http\Kernel::class,
App\Http\Kernel::class
);

// console处理
$app->singleton(
Illuminate\Contracts\Console\Kernel::class,
App\Console\Kernel::class
);

// 异常处理
$app->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::class,
App\Exceptions\Handler::class
);


创建Kernel,注意这里是基于接口来创建, 最终创建什么实例, 依赖于前面的接口绑定。

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);


这个代码最终实例化的是App\Http\Kernel,App\Http\Kernel继承自Illuminate\Foundation\Http\Kernel。

接口绑定是laravel框架设计精华所在,laravel框架的核心组件全部都实现了接口,在laravel里统一放在Contracts下。这给予了开发者极大的自由,可以在程序中通过修改接口绑定来改变组件的实现。

chunfang@office:~/base.account$ ls vendor/laravel/framework/src/Illuminate/Contracts/
Auth          Bus    composer.json  Console    Cookie    Debug       Events
Foundation  Http     Mail        Pipeline  Redis    Support     View
Broadcasting  Cache  Config         Container  Database  Encryption  Filesystem
Hashing     Logging  Pagination  Queue     Routing  Validation


基于全局变量创建request对象, 交由Kernel处理, 这是请求处理的核心所在。

基于全局变量创建请求

$request = Illuminate\Http\Request::capture()


Kerner处理request

$response = $kernel->handle($request);

请求方法关键细节:

/**
* Handle an incoming HTTP request.
*
* @param  \Illuminate\Http\Request  $request
* @return \Illuminate\Http\Response
*/
public function handle($request)
{
try {
// 允许使用_method来模拟PUT,DELETE等
$request->enableHttpMethodParameterOverride();

// 处理请求返回响应
$response = $this->sendRequestThroughRouter($request);
} catch (Exception $e) {
$this->reportException($e);

$response = $this->renderException($request, $e);
} catch (Throwable $e) {
$this->reportException($e = new FatalThrowableError($e));

$response = $this->renderException($request, $e);
}

// 发射事件
$this->app['events']->fire('kernel.handled', [$request, $response]);

return $response;
}

处理请求返回响应关键细节:

/**
* Send the given request through the middleware / router.
*
* @param  \Illuminate\Http\Request  $request
* @return \Illuminate\Http\Response
*/
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());
}

初始化资源关键细节:

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',
];

流水线实现细节:
理解Laravel中的pipeline

路由处理关键细节:

/**
* Dispatch the request to the application.
*
* @param  \Illuminate\Http\Request  $request
* @return \Illuminate\Http\Response
*/
public function dispatch(Request $request)
{
$this->currentRequest = $request;

$response = $this->dispatchToRoute($request);

return $this->prepareResponse($request, $response);
}

/**
* Dispatch the request to a route and return the response.
*
* @param  \Illuminate\Http\Request  $request
* @return mixed
*/
public function dispatchToRoute(Request $request)
{
// First we will find a route that matches this request. We will also set the
// route resolver on the request so middlewares assigned to the route will
// receive access to this route instance for checking of the parameters.
$route = $this->findRoute($request);

$request->setRouteResolver(function () use ($route) {
return $route;
});

$this->events->fire(new Events\RouteMatched($route, $request));

$response = $this->runRouteWithinStack($route, $request);

return $this->prepareResponse($request, $response);
}

路由执行实际动作关键细节:

/**
* Run the route action and return the response.
*
* @param  \Illuminate\Http\Request  $request
* @return mixed
*/
public function run(Request $request)
{
$this->container = $this->container ?: new Container;

try {
if (! is_string($this->action['uses'])) {
return $this->runCallable($request);
}

return $this->runController($request);
} catch (HttpResponseException $e) {
return $e->getResponse();
}
}


输出到客户端

$response->send();


依次调用结束动作

$kernel->terminate($request, $response);


IOC容器的实现

编写中

实现自己的路由替代Laravel路由

编写中

浅析资源初始化

编写中

Laravel Pipeline的实现

编写中

基于Stone实现高性能Kernel

编写中
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  php laravel