Lumen开发:lumen源码解读之初始化(1)——app实例
版权声明:本文为博主原创文章,未经博主允许不得转载。
有些注释来着原文的百度翻译,可以有些难理解或者奇怪,我后面会根据自己的理解做调整的哈!!!不喜勿喷,层主英语不过关。。。
先来看看入口文件public/index.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | //请求头 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了
1 2 3 4 5 6 7 | require_once __DIR__ . '/../vendor/autoload.php' ; try { ( new Dotenv\Dotenv(__DIR__ . '/../' ))->load(); } catch (Dotenv\Exception\InvalidPathException $e ) { // } |
这里是引入Composer的包,之前讲过,这里不详谈。Dotenv是env配置的使用。
往下看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /* |-------------------------------------------------------------------------- | Create The Application(创建应用程序) |-------------------------------------------------------------------------- | | 在这里,我们将加载环境并创建作为该框架的中心部分的应用程序实例。<br>| 我们将使用这个应用程序作为这个框架的“IOC”容器和路由器。 | */ $app = new Laravel\Lumen\Application( realpath (__DIR__ . '/../' ) ); $app ->withFacades(); $app ->withEloquent(); |
1 | Laravel\Lumen\Application |
class Application extends Container
{
use Concerns\RoutesRequests,
Concerns\RegistersExceptionHandlers;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | ...<br> /** * 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(); } |
1 | 这个可以说是整个Lumen应用程序最最核心的类了,上继承了核心容器类(Container),左右引用了Concerns\RoutesRequests(路由),Concerns\RegistersExceptionHandlers(异常处理),下又实例了app对象,很是重要喔!!!<br><br> $this ->bootstrapContainer(); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /** * 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()函数
1 2 3 4 5 6 7 8 9 10 | /** * 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()函数了,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /** * Register an existing instance as shared in the container.(登记一个现有的实例所共享的容器。) */ public function instance( $abstract , $instance ) { $this ->removeAbstractAlias( $abstract ); //从上下文绑定缓存中删除一个别名。 $isBound = $this ->bound( $abstract ); //确定给定的类型已被绑定。 unset( $this ->aliases[ $abstract ]); //删除对应注册类型别名。 //TODO 翻译修正<br> //检查以确定此类型是否已被绑定, //如果有我们将触发与容器注册的回调和反射可以消费类已经解决这里的更新。 $this ->instances[ $abstract ] = $instance ; if ( $isBound ) { $this ->rebound( $abstract ); //触发回调给定的抽象类型 } } |
再到$this->registerContainerAliases()函数,这个函数用于注释核心容器的别名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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(),既然是异常处理,肯定是在Concerns\RegistersExceptionHandlers(异常处理)里了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /** * 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(); }); } |
这部分后面在写一篇文做补充,http://...
到这里,$app应用程序就初始好了,下一篇会接着讲
1 2 3 | $app ->withFacades(); //为应用程序注册门面。 $app ->withEloquent(); //为应用程序加载功能强大的库。 |
和后面的内容!!!
版权声明:本文为博主原创文章,未经博主允许不得转载。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· 因为Apifox不支持离线,我果断选择了Apipost!