laravel框架底层解析
本文参考陈昊《Laravel框架关键技术解析》,搭建一个属于自己的简化版服务容器。
其中涉及到反射、自动加载,还是需要去了解一下。laravel服务容器
建立项目空文件夹(如 mylaravel)
添加
composer.json
,执行composer install
{ "name": "laravel/laravel", "description": "The Laravel Framework.", "keywords": ["framework", "laravel"], "license": "MIT", "type": "project", "autoload": { "classmap": [ ], "psr-4": { "App\\": "app/" } }}
目的是为了学习、利用composer的自动加载。
文件路径如下所示
-
mylaravel
-
app
-
Traveller
Traveller.php
-
Visit
Leg.php
Visit.php
Container.php
Index.php
-
vendor
composer.json
-
简化版
Container.php
getClosure($abstract, $concrete); } $this->bindings[$abstract] = compact('concrete', 'shared'); } //默认的回调函数 protected function getClosure($abstract, $concrete) { //生成实例的回调函数, $c一般为ioc容器对象 return function($c) use ($abstract, $concrete) { $method = ($abstract == $concrete) ? 'build' : 'make'; return $c->$method($concrete); }; } //生成实例对象,首先解决接口和要实例化类之间的依赖 public function make($abstract) { $concrete = $this->getConcrete($abstract); if ($this->isBuildable($concrete, $abstract)) { $object = $this->build($concrete); } else { $object = $this->make($concrete); } return $object; } protected function isBuildable($concrete, $abstract) { return $concrete === $abstract || $concrete instanceof \Closure; } //获取绑定的回调函数 protected function getConcrete($abstract) { if ( ! isset($this->bindings[$abstract])) { return $abstract; } return $this->bindings[$abstract]['concrete']; } //实例化对象 public function build($concrete) { if ($concrete instanceof \Closure) { return $concrete($this); } $reflector = new \ReflectionClass($concrete); if ( ! $reflector->isInstantiable()) { echo $message = "Target [$concrete] is not instantiable."; } $constructor = $reflector->getConstructor(); if (is_null($constructor)) { return new $concrete; } $dependencies = $constructor->getParameters(); $instances = $this->getDependencies($dependencies); return $reflector->newInstanceArgs($instances); } protected function getDependencies($parameters) { $dependencies = []; foreach ($parameters as $parameter) { $denpendency = $parameter->getClass(); if (is_null($denpendency)) { $dependencies[] = NULL; } else { $dependencies[] = $this->resolveClass($parameter); } } return (array) $dependencies; } protected function resolveClass(\ReflectionParameter $parameter) { return $this->make($parameter->getClass()->name); }}
Visit.php
接口
Leg.php
接口的一种实现
Traveller.php
相当于Controller下的方法
trafficTool = $visit; } public function visitTibet() { $this->trafficTool->go(); }}
Index.php
bind('App\Visit\Visit', '\App\Visit\Leg'); $app->bind('Traveller', '\App\Traveller\Traveller'); //通过容器实现依赖注入,完成类的实例化 $tra = $app->make("\App\Traveller\Traveller"); $tra->visitTibet(); }}$b = new Index;$b->index();