Slim容器分析

5年前,我还没什么编程经验,第一次接触java的spring框架,了解容器容器的概念,立刻被它巧妙的设计所惊呆,没错,就是惊呆...没想到程序居然可以这么写!!

不是从上至下的命令式编程,不是分而治之的结构式编程,也不是我当时水平所认知的自底向上,相互作用的对象式编程,而是可复用,可替换的组件化编程。

后来一直做PHP Web应用开发,也没机会用Spring做一些应用,一直在想PHP什么时候也能有使用容器的框架就好了。

一次偶然机会,在一个技术qq群,有人推荐一个叫Slim的框架,我随手打开github,看看这个框架源码,又惊呆了,Slim里有容器,而且惊叹现在的PHP框架怎么越来越像Java Web的框架,有容器,有组件,全OOP。

Slim的源代码地址Github

附Slim资料链接:

以日志组件为例,来看看PHP是怎么配置组件,怎么讲组件注入容器,怎么实例化组件,以及何时实例化组件和调用组件的方法?

入口文件

Slim/public/index.php

所有请求都是发送给入口文件,然后由入口文件分发请求到相应的服务,入口文件很简单,我截取了和主题相关的部分。

// 包含应用配置文件

$settings = require __DIR__ . '/../src/settings.php';

// 初始化应用

$app = new \Slim\App($settings);

// 注入应用所依赖组件

// Set up dependencies

require __DIR__ . '/../src/dependencies.php';

配置组件

Slim/src/settings.php

其中就包含了logger组件的配置信息:

日志组件的名字:slim-app

日志组件的log记录保存的位置:_DIR_ . '/../logs/app.log',

return [

'settings' => [

'displayErrorDetails' => true, // set to false in production

'addContentLengthHeader' => false, // Allow the web server to send the content-length header

// Renderer settings

'renderer' => [

'template_path' => __DIR__ . '/../templates/',

],

// Monolog settings

'logger' => [

'name' => 'slim-app',

'path' => __DIR__ . '/../logs/app.log',

],

],

];

注入组件 - 依赖注入

应用初始化之后,开始向容器注入应用所依赖的组件。

在Slim/src/dependencies.php里面定义了应用所依赖的组件,比如模板组件、日志组件、数据库组件等等。

我们就取其中logger组件来分析分析

// monolog

$container['logger'] = function ($container) {

$settings = $container->get('settings')['logger'];

$logger = new Monolog\Logger($settings['name']);

$logger->pushProcessor(new Monolog\Processor\UidProcessor());

$logger->pushHandler(new Monolog\Handler\StreamHandler($settings['path'], Monolog\Logger::DEBUG));

return $logger;

};

这里将一个回调函数赋值给一个容器实例的“logger”属性,

研究一下这个回调函数:

回调函数的参数是一个容器实例,回调函数体通过这个容器实例获取logger组件的配置信息,根据配置信息实例化组件,最后返回这个组件实例。

将这样一个实例化组件的回调函数交给容器,就实现logger组件的注入——这种注入,通过回调函数注入依赖是依赖注入的一种实现方法。

这也是控制反转的一种实现,把原本由应用程序实例化组件,交给了低层容器去做。

实例化组件

那么把实例化得控制权交给容器,那么容器什么时候实例化组件呢?

答案是,在第一次调用组件的时候。

Slim/src/routes.php

app->get('/[{name}]', function ($request, $response, $args) {

// Sample log message

$this->logger->info("Slim-Skeleton '/' route");

// Render index view

return $this->renderer->render($response, 'index.phtml', $args);

});

在执行下面语句时,如果logger组件没有实例化,就实例logger组件,将实例保存在容器中,并且返回logger组件实例;如果容器中已经有logger组件的实例,就返回该实例——单例模式。

$this->logger->info("Slim-Skeleton '/' route");

$this指向容器,这里使用了php的魔术方法__get()去获取容器的内的属性。

Slim/vendor/slim/slim/Slim/Container.php

/********************************************************************************

* Magic methods for convenience

*******************************************************************************/

public function __get($name)

{

return $this->get($name);

}

最后调用下面方法放回logger组件的实例。

public function offsetGet($id)

{

if (!isset($this->keys[$id])) {

throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));

}

if (

isset($this->raw[$id])

|| !is_object($this->values[$id])

|| isset($this->protected[$this->values[$id]])

|| !method_exists($this->values[$id], '__invoke')

) {

return $this->values[$id];

}

if (isset($this->factories[$this->values[$id]])) {

return $this->values[$id]($this);

}

$raw = $this->values[$id];

$val = $this->values[$id] = $raw($this);

$this->raw[$id] = $raw;

$this->frozen[$id] = true;

return $val;

}

其中最关键是这一句

$val = $this->values[$id] = $raw($this);

$raw是前面提到的logger的回调函数,通过$raw($this)去调用回调函数,返回logger组件的实例。

紧接着做了两件事:

一是赋值给$this->values[$id],作为一个单例保存在容器中,之后再次调用logger组件时,直接返回这个单例。

二是将logger组件实例赋值给$val,作为整个方法的返回值,返回到logger组件的调用处,也就是回到了之前调用logger组件的info()方法处,见下面代码,这样就能写日志到app.log文件里了,

Slim/src/routes.php

$this->logger->info("Slim-Skeleton '/' route");

现代制造工业模式

容器组件化编程,让我想起现代制造工业模式,比如汽车制造业。

最初汽车制造商所有汽车零件都是自己生产组装。

现代汽车厂商已经将汽车零件外包给第三方工厂。

汽车制造商只需要与第三方工厂签到合同,提供标准。

第三方工厂自行安排具体的零件生产工作。

汽车制造商需要汽车时,就从第三方工厂取货,组装汽车。

在这里汽车制造商就是就是容器,汽车就是应用程序,汽车零件就是组件。

看来不仅面向对象编程是对现实的抽象,软件设计思想也是来源现实世界的抽象

最后总结下来,Slim容器有2个特点:

使用回调函数实现依赖注入,达到控制反转的目的。

在使用组件时,才实例化组件,并单例化。

slim php 优点,Slim容器分析相关推荐

  1. 新西兰.net和java_使用Linux容器分析气候变化和土壤对新西兰农作物的影响

    新西兰.net和java 新西兰的经济取决于农业,农业对气候变化高度敏感. 这使得开发分析功能以评估其影响并调查可能的缓解和适应方案至关重要. 可以使用诸如农业系统模型之类的工具进行分析. 简而言之, ...

  2. slim mysql_在 Slim 中使用 Eloquent

    在 Slim 中使用 Eloquent 你可以使用 Eloquent 这种数据库 ORM 将你的 Slim 应用程序连接到数据库. 为你的应用程序添加 Eloquent composer requir ...

  3. php slim框架 教程,Slim —— PHP web开发微框架

    Slim是一款基于PHP的web开发微框架,帮助 PHP 开发者快速编写简单强大的web应用和API.Slim的接口简单而符合直觉,文档也很详细. 直接看一段代码吧: $app->get('/' ...

  4. Spring IOC容器分析(1) -- BeanFactory

    搭建好源码阅读环境后,就可以慢慢走进Spring殿堂了.IOC是Inversion of Control的缩写,控制反转的意思.很多人可能都知道IOC是spring的核心,将对象的创建初始化等权限交由 ...

  5. Slim 4 PHP 框架零基础学习笔记-依赖容器

    1.什么是依赖容器 Slim 框架使用依赖容器来预载.管理和注入应用依赖.支持 PSR-11 或 Container-Interop 标准接口形式,框架内置 Pimple 容器,也可以使用 Accli ...

  6. Slim 框架源码解读

    0x00 前言 Slim 是由<PHP The Right Way>作者开发的一款 PHP 微框架,代码量不算多(比起其它重型框架来说),号称可以一下午就阅读完(我觉得前提是熟悉 Slim ...

  7. 【Tensorflow】Tensorflow中的卷积函数(conv2d、slim.conv2d、depthwise_conv2d、conv2d_transpose)

    [fishing-pan:https://blog.csdn.net/u013921430 转载请注明出处] 前言   卷积是卷积神经网络中最主要.最重要的运算.想必大家最早接触卷积的概念就是在初高中 ...

  8. 对Slim 框架进行总结 一

    导读:今天我们来看看中间件的相关功能 中间件 Slim中的中间件分两种:应用级中间件.路由级中间件. 应用中间件基于Rack协议实现,可以在应用对象调用之前或之后检查.分析.或修改应用环境变量.请求对 ...

  9. php slim 教程,Slim - 超轻量级PHP Restful API构建框架

    下载源码包: http://www.slimframework.com/ 基于Slim的Restful API Sample: require '/darjuan/Slim/Slim.php'; us ...

最新文章

  1. java中的重载和重写
  2. java 线程中断(转)
  3. ++ 多核cpu 并行_一文读懂什么是多核并行计算(三)
  4. simuvex 符号分析形象解释
  5. Linux API函数总结
  6. echarts实现省份迁徙图
  7. sdk寄存器地址linux,S32K SDK使用详解之PinSettings组件配置与使用详解(S32K1xx PORT 和GPIO模块)...
  8. WPF做的金山词霸页面
  9. 计算机识别不到硬盘,电脑认不到硬盘怎么回事 电脑开机认不到硬盘处理方法...
  10. 用自己的APP打开微信和支付宝付款码和扫一扫界面
  11. 项目管理论坛_活动预告|2019年“VUCA时代项目管理与项目治理”论坛通知
  12. python 监控键盘输入_python 监控键盘输入
  13. HDU 6578 Blank 区间dp
  14. 部分HTTPS网站无法访问的可能原因
  15. 计算机管理员无法关闭防火墙,Win10关闭防火墙提示:出于安全原因 某些设置由系统管理员管理的解决方法...
  16. ‘数据分析实战’——营销组合分析(甲厨电公司案例)
  17. [EDA]实验2A:设计M=12的计数器
  18. Git和SourceTree入门教程
  19. 玩银河麒麟操作系统终端,忆国外unix主机上偶遇隔壁同胞
  20. 【天光学术】经济法论文:高校电信诈骗的主要表现形式及其防范策略【开题报告 法学硕士研究生毕业论文】

热门文章

  1. vue-cli3封装组件库打包并发布npm开源包和npm内网私有库
  2. 使用wget命令出现 Resolving mirrors.tuna.tsinghua.edu.cn (--no-check-certificate)
  3. majordomo邮件列表快速安装指南
  4. 获取Windows7特殊文件夹的权限
  5. 爱前端视频课程全套 初级+中级+高级
  6. 用PowerShell批量收回wsp包
  7. word wrap.mysql_Mysql远程连接,并解决wordp主题添加问题
  8. 博达3616系列OLT河北广电Qinq配置
  9. js使用canvas 绘画 画板 签名墙
  10. EternalBlue(永恒之蓝)漏洞