1. 云栖社区>
  2. PHP教程>
  3. 正文

Laravel服务容器

作者:用户 来源:互联网 时间:2017-12-01 17:59:38

laravel容器服务

Laravel服务容器 - 摘要: 本文讲的是Laravel服务容器,laravel框架底层解析本文参考陈昊《Laravel框架关键技术解析》,搭建一个属于自己的简化版服务容器。其中涉及到反射、自动加载,还是需要去了解一下。 laravel服务容器建立项目空文件夹(如 mylaravel) 添加compose

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


<?php
namespace App;Class Container
{
protected $bindings = [];/**
* 绑定接口和生成相应实例的回调函数
* @param $abstract 服务名称
* @param null $concreate 回调函数或名称
* @param bool $shared 是否为单例
*
*/
public function bind($abstract, $concrete = null, $shared = false)
{
if ( ! $concrete instanceof /Closure) {
// 如果提供的参数不是回调函数,则产生默认的回调函数
$concrete = $this->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接口


<?php
namespace App/Visit;interface Visit
{
public function go();
}

Leg.php接口的一种实现


<?php
namespace App/Visit;Class Leg implements Visit
{
public function go()
{
echo "walk to tibet!";
}
}

Traveller.php相当于Controller下的方法


<?php
namespace App/Traveller;use App/Visit/Visit;Class Traveller
{
protected $trafficTool;
//Visit是抽象类,index中将leg注入到了容器,取代了Visit
public function __construct(Visit $visit)
{
$this->trafficTool = $visit;
}
public function visitTibet()
{
$this->trafficTool->go();
}
}

Index.php


<?php
namespace App;//调用composer的自动加载
require '../vendor/autoload.php';Class Index
{
public function index()
{
//实例化ioc容器
$app = new Container();
//容器填充
$app->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();

以上是云栖社区小编为您精心准备的的内容,在云栖社区的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索laravel , 容器 服务 ,以便于您获取更多的相关知识。