Laravel源码解析一 【请求的生命周期】
来源:互联网 发布:程序员开发软件 编辑:程序博客网 时间:2024/05/17 19:16
不BB,直接开始。
看一个框架的源码,第一步我们先看入口文件。
laravel的入口文件在public目录下的index.php
require __DIR__.'/../bootstrap/autoload.php';
这玩意是加载composer的一些东西,自动加载有需要的类。具体的也不多说,主要是我还没玩会这玩意。
接着看
$app = require_once __DIR__.'/../bootstrap/app.php';
这里要看bootstrap目录下的app.php文件
这个文件里映入眼帘的就是
$app = new Illuminate\Foundation\Application( realpath(__DIR__.'/../'));
好吧。new一个application出来。那么我们找到Illuminate\Foundation\Application这个文件
public function __construct($basePath = null) { $this->registerBaseBindings(); $this->registerBaseServiceProviders(); $this->registerCoreContainerAliases(); if ($basePath) { $this->setBasePath($basePath); } }
new application时的构造函数长这个样子。写到这的时候,我突然觉得加个序号可能会比较好。
(一) new Application的过程
1.1先是注册基本绑定,也就是 $this->registerBaseBindings();这个方法里的内容
protected function registerBaseBindings() { static::setInstance($this); $this->instance('app', $this); $this->instance('Illuminate\Container\Container', $this); }
巨简单的过程,就是把实例化的的application 赋值给app和Illuminate\Container\Container
1.2注册基本的服务提供者。$this->registerBaseServiceProviders();
protected function registerBaseServiceProviders() { $this->register(new EventServiceProvider($this)); $this->register(new RoutingServiceProvider($this)); }
这里通过名字可以感觉出是注册了事件服务提供者和路由服务提供者
1.3注册核心类名的别名$this->registerCoreContainerAliases();
public function registerCoreContainerAliases() { $aliases = [ 'app' => ['Illuminate\Foundation\Application', 'Illuminate\Contracts\Container\Container', 'Illuminate\Contracts\Foundation\Application'], 'auth' => ['Illuminate\Auth\AuthManager', 'Illuminate\Contracts\Auth\Factory'], 'auth.driver' => ['Illuminate\Contracts\Auth\Guard'], 'blade.compiler' => ['Illuminate\View\Compilers\BladeCompiler'], 'cache' => ['Illuminate\Cache\CacheManager', 'Illuminate\Contracts\Cache\Factory'], 'cache.store' => ['Illuminate\Cache\Repository', 'Illuminate\Contracts\Cache\Repository'], 'config' => ['Illuminate\Config\Repository', 'Illuminate\Contracts\Config\Repository'], 'cookie' => ['Illuminate\Cookie\CookieJar', 'Illuminate\Contracts\Cookie\Factory', 'Illuminate\Contracts\Cookie\QueueingFactory'], 'encrypter' => ['Illuminate\Encryption\Encrypter', 'Illuminate\Contracts\Encryption\Encrypter'], 'db' => ['Illuminate\Database\DatabaseManager'], 'db.connection' => ['Illuminate\Database\Connection', 'Illuminate\Database\ConnectionInterface'], 'events' => ['Illuminate\Events\Dispatcher', 'Illuminate\Contracts\Events\Dispatcher'], 'files' => ['Illuminate\Filesystem\Filesystem'], 'filesystem' => ['Illuminate\Filesystem\FilesystemManager', 'Illuminate\Contracts\Filesystem\Factory'], 'filesystem.disk' => ['Illuminate\Contracts\Filesystem\Filesystem'], 'filesystem.cloud' => ['Illuminate\Contracts\Filesystem\Cloud'], 'hash' => ['Illuminate\Contracts\Hashing\Hasher'], 'translator' => ['Illuminate\Translation\Translator', 'Symfony\Component\Translation\TranslatorInterface'], 'log' => ['Illuminate\Log\Writer', 'Illuminate\Contracts\Logging\Log', 'Psr\Log\LoggerInterface'], 'mailer' => ['Illuminate\Mail\Mailer', 'Illuminate\Contracts\Mail\Mailer', 'Illuminate\Contracts\Mail\MailQueue'], 'auth.password' => ['Illuminate\Auth\Passwords\PasswordBrokerManager', 'Illuminate\Contracts\Auth\PasswordBrokerFactory'], 'auth.password.broker' => ['Illuminate\Auth\Passwords\PasswordBroker', 'Illuminate\Contracts\Auth\PasswordBroker'], 'queue' => ['Illuminate\Queue\QueueManager', 'Illuminate\Contracts\Queue\Factory', 'Illuminate\Contracts\Queue\Monitor'], 'queue.connection' => ['Illuminate\Contracts\Queue\Queue'], 'queue.failer' => ['Illuminate\Queue\Failed\FailedJobProviderInterface'], 'redirect' => ['Illuminate\Routing\Redirector'], 'redis' => ['Illuminate\Redis\Database', 'Illuminate\Contracts\Redis\Database'], 'request' => ['Illuminate\Http\Request', 'Symfony\Component\HttpFoundation\Request'], 'router' => ['Illuminate\Routing\Router', 'Illuminate\Contracts\Routing\Registrar'], 'session' => ['Illuminate\Session\SessionManager'], 'session.store' => ['Illuminate\Session\Store', 'Symfony\Component\HttpFoundation\Session\SessionInterface'], 'url' => ['Illuminate\Routing\UrlGenerator', 'Illuminate\Contracts\Routing\UrlGenerator'], 'validator' => ['Illuminate\Validation\Factory', 'Illuminate\Contracts\Validation\Factory'], 'view' => ['Illuminate\View\Factory', 'Illuminate\Contracts\View\Factory'], ]; foreach ($aliases as $key => $aliases) { foreach ($aliases as $alias) { $this->alias($key, $alias); } } }
这个方法更简单,就是一个别名数组,然后通过for循环调用$this->alias()给Application类的父类Container里的aliases数组里。
1.4设置基本路径,我们在new Application时传入的 realpath(DIR.’/../’)这个参数赋值给基本路径
(二)注册共享的Kernel和异常处理器
我们的app也new好了,我们接着app.php里往下走可以看到
$app->singleton( Illuminate\Contracts\Http\Kernel::class, App\Http\Kernel::class);$app->singleton( Illuminate\Contracts\Console\Kernel::class, App\Console\Kernel::class);$app->singleton( Illuminate\Contracts\Debug\ExceptionHandler::class, App\Exceptions\Handler::class);
这三个具体干嘛的我们以后分析,然后app.php最后返回的是app实例
(三)处理请求和响应
app.php文件执行完以后回到index.php 可以看到
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);$response = $kernel->handle( $request = Illuminate\Http\Request::capture());$response->send();$kernel->terminate($request, $response);
3.1解析Illuminate\Contracts\Http\Kernel,实例化App\Http\Kernel
3.2实例化后的kernel处理本次请求。这里$kernel->handle()传入的参数是一个request。
这里的request是经过Symfony封装的请求对象。讲道理看到这的时候我有点懵逼。卧槽,我刚开始学laravel,还没整明白呢,就又多了一个Symfony要学,至少得了解怎么封装的请求对象。好烦呀。。。
3.3是将请求处理后的返回结果发送到浏览器里
3.4处理继承自TerminableMiddleware接口的中间件(Session)并结束应用生命周期。
以上就是laravel框架里执行一次请求所要经历的生命周期。
具体的如何注册如何加载如何封装请求,我会随着自己知识的积累和分析源码来做出解答。
顺便,我也是刚开始学习laravel。一起加油!
- Laravel源码解析一 【请求的生命周期】
- 【Laravel】 的请求生命周期
- Laravel 5.x 请求的生命周期
- Laravel 请求生命周期流程图
- Laravel源码(流程)解析
- Glide源码解析:加载请求与生命周期绑定
- django源码解析一(请求处理流程)
- laravel源码阅读之应用生命周期
- 196 laravel 源码解析-3
- 关于Laravel的二、三事(1)一次请求的生命周期
- 从源码来看Fragment的生命周期(一)
- laravel源码分析(一)
- 4、Volley解析(二),源码的深入分析一,缓存线程和网络请求线程
- Volley源码解析(一):网络请求内容
- OKHttp源码解析一(网络请求篇)
- laravel中的$request对象构造及请求生命周期
- Laravel生命周期
- Flume 源码解析:组件生命周期
- 电子词典
- 【Linux 系统 连接网络、固定IP】
- Scala速成
- IP地址与子网掩码
- tnsping命令详解
- Laravel源码解析一 【请求的生命周期】
- SSH商城Demo --- 二、需求分析
- Android蓝牙配对弹出框过程分析
- 十一,linux中配置jdk8环境
- Centos 6.5 编译Install SVN-1.9.5
- Linux 上的 MAC 地址欺骗
- 意外把移动硬盘标记为活动分区怎么办?
- JDK并发包---(5)重入锁ReentrantLock:公平锁
- windows下查找java应用占用CPU过高问题