laravel框架底层解析

本文参考陈昊《Laravel框架关键技术解析》,搭建一个属于自己的简化版服务容器。
其中涉及到反射、自动加载,还是需要去了解一下。

laravel服务容器

  1. 建立项目空文件夹(如 mylaravel)

  2. 添加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的自动加载。

  1. 文件路径如下所示

  • mylaravel

    • app

      • Traveller

        • Traveller.php

      • Visit

        • Leg.php

        • Visit.php

      • Container.php

      • Index.php

    • vendor

    • composer.json

  1. 简化版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服务容器的更多相关文章

  1. Laravel 服务容器、服务提供器、契约实例讲解

        前言 刚开始看laravel服务容器.契约.服务提供器的确生涩难懂,不单单是概念繁多,而且实际的demo很难找(找是找到了,但难用啊),最后就隔一段时间看一遍,大概个十来遍,还真给看出个门道, ...

  2. Laravel 服务容器实例教程 —— 深入理解控制反转(IoC)和依赖注入(DI)

    容器,字面上理解就是装东西的东西.常见的变量.对象属性等都可以算是容器.一个容器能够装什么,全部取决于你对该容器的定义.当然,有这样一种容器,它存放的不是文本.数值,而是对象.对象的描述(类.接口)或 ...

  3. Laravel服务容器的绑定与解析

    本篇文章给大家带来的内容是关于Laravel服务容器的绑定与解析,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 前言   老实说,第一次老大让我看laravel框架手册的那天早上,我 ...

  4. 关于使用 Laravel 服务容器的优势介绍

    如果说laravel框架的核心是什么,那么无疑是服务容器.理解服务容器的概念,对于我们使用laravel太重要了,应该说是否理解服务容器的概念是区分是否入门laravel的重要条件.因为整个框架正是在 ...

  5. laravel服务容器 转

    laravel框架底层解析 本文参考陈昊<Laravel框架关键技术解析>,搭建一个属于自己的简化版服务容器.其中涉及到反射.自动加载,还是需要去了解一下. laravel服务容器 建立项 ...

  6. laravel 服务容器实现原理

    前言 通过实现laravel 框架功能,以便深入理解laravel框架的先进思想. 什么是服务容器 服务容器是用来管理类依赖与运行依赖注入的工具.Laravel框架中就是使用服务容器来实现 ** 控制 ...

  7. laravel服务容器-----深入理解控制反转(IoC)和依赖注入(DI)

    首先大家想一想什么是容器,字面意思就是盛放东西的东西,常见的变量,对象属性都是容器,一个容器能够装什么东西,完全在于你对这个容器的定义.有的容器不仅仅只是存文本,变量,而是对象,属性,那么我们通过这种 ...

  8. Laravel 服务容器,IoC,DI

    DI DI 就是常说的依赖注入,那么究竟什么是依赖注入呢? 打个比方,电脑(非笔记本哈)需要键盘和鼠标我们才能进行操作,这个‘需要’换句话说就是‘依赖’键盘和鼠标. 那么,相应的,一个类需要另一个类才 ...

  9. laravel 服务容器

    服务容器,也叫IOC容器,其实包含了依赖注入(DI)和控制反转(IOC)两部分,是laravel的真正核心.其他的各种功能模块比如 Route(路由).Eloquent ORM(数据库 ORM 组件) ...

随机推荐

  1. Java Native Interface(JNI)

    JNI能让Java代码在Java虚拟机里调用其他编程语言(例如C.C++)写的应用或库,且不会影响任何Java虚拟机的实现. 什么时候用JNI? 1.应用程序所需的平台相关功能,标准的Java类库不支 ...

  2. CORS(跨域资源共享)详解及与JSONP的对比

    上篇讲解的JSONP的跨域请求方式,但是在浏览器的支持及请求方式上有局限性,接下来将介绍一种新的跨域请求方式CORS. CORS是一个W3C标准,全称是"跨域资源共享"(Cross ...

  3. IT部门不应该是一个后勤部门

    管理上最大的问题在于不重视预算与核算的管理.从管理层到员工,很少有经营的念头,只是一味地埋头做事.西方企业总结了当今几百年的经营理念,最终把企业一切活动的评价都归结到唯一的.可度量的标准上:钱来度量. ...

  4. JS页面打印

    平常浏览网页和文档的时候,随处可见打印两个字,有时候不小心点到或者快捷键触发到,就会弹出一个打印的页面,上边显示的打印机是GoldGrid Virtual Printer,这是计算机的虚拟打印机,打印 ...

  5. vue-router 管理视图详解

    什么是路由 在web开发中,路由是指根据url分配到对应的处理程序,当访问不同的url就会切换到对应的处理程序 在vue中一个url对应的就是一个组件,当访问不同的url,对应的组件就会呈现到页面中 ...

  6. Navicat 链接mysql 显示 Clinet dose not support authentication protocol request by server ;consider upgrading MySQL client

    1  在命令窗口 输入mysql -uroot -p 首先通过cmd进入mysql 2 更改加密方式 mysql> ALTER USER 'root'@'localhost' IDENTIFIE ...

  7. UVA1374-Power Calculus(迭代加深搜索)

    Problem UVA1374-Power Calculus Accept:323  Submit:2083 Time Limit: 3000 mSec  Problem Description  I ...

  8. 【html】使ifram搭建的项目,新页面跳出框架

    方法一: <a href="<?php echo $baseUrl . '#/study/order';?>" target="_parent" ...

  9. Oracle查询数据库中所有表的记录数

    1.Oracle查询数据库中所有表的记录数,但是有可能不准建议用第二种方式进行查询 select t.table_name,t.num_rows from user_tables t 2.创建orac ...

  10. nginx+tomcat9+redisson+redis+jdk1.8简单实现session共享

    一.环境安装 由于资源限制,在虚拟机中模拟测试,一台虚拟机,所有软件均安装到该虚拟机内 安装系统:CentOS Linux release 7.4.1708 (Core) CentOS安装选择版本:B ...