您的位置:首页 > 编程语言 > PHP开发

移植 Laravel 核心组件:如何给 TP3.1 用上 IoC 容器 (一)

2015-09-17 10:14 676 查看
单位的主项目是用ThinkPHP 3.1 开发的. 功能越来越跟不上发展 , 而老代码迭代的难度又很大 . 重构已经提上了日程, 但抛下主营业务来重构是不实际的 . 所以目前的思路是 , 将原有功能拆分成一个个独立的组件 , 脱离ThinkPHP 3.1 运行, 未来再移植到新架构里.

用惯了Laravel的人 , 自然很快想到了引入Laravel的IoC容器 . 它有以下好处:

可以用来管理各种复杂的依赖关系

方便引入第三方依赖包

可以面向接口来规范重构

利于迭代,一组依赖中,旧的实例可以逐个改成新的实例,而不影响调用

可以用facade为功能模块提供简洁的Api接口

未来可直接引入laravel的 队列, 事件, EloquentORM 等核心机制

那么在ThinkPHP引入IoC , 需要几步呢?如下:

确保ThinkPHP 3.1 项目运行在 php 5.4 以上环境中

给ThinkPHP 3.1 引入Composer

独立出Laravel的Container组件

为扩展功能设计架构

创建引入ThinkPHP的引导文件

一. 给ThinkPHP 3.1 引入Composer

时至今日 , ThinkPHP自身的autoload管理功能已经非常老旧了 , 有这几个关键的痛点:

没有命名空间,大量关键类同名

引入外部库还要用令人费解的import()方法

生成autoload的代码位置 , 在设计理念上有错

靠ThinkPHP去管理各种现代依赖 , 基本是不可能完成的任务 . 这时Composer就大显身手了.

我们可以在任意文件夹创建
Composer.json
文件 , 然后按自己的设想任意构建扩展.

运行
composer install
指令后,composer就自动为我们下载了所有依赖,并生成了
vendor/autoload.php
文件.

瞥一眼
vendor/autoload.php
文件,会发现它其实就干了两件事 :

引入了
vendor/composer/ClassLoader.php
,这里注册了各种 Autoload 机制的引用文件方法

引入了按
composer.json
文件定义的classmap,files,psr-0,psr-4等规范 , 生成的类名路径映射关系文件.

所以我们只要把
vendor/autoload.php
在ThinkPHP项目中
require
进来, 就可以随心所欲使用任何自定义类和扩展,再不要受TP3.1规范的约束了.

问题是
autoload.php
要在哪里引入比较合适呢? 经过反复测试,还是在
Public/index.php
中引入较好:

/**
* 系统调试设置
* 项目正式部署后请设置为false
*/
define ( 'APP_DEBUG', true );
define ( 'APP_PATH', realpath(dirname(__FILE__) ."/../") ."/" );
define ( 'WEB_PATH', realpath(dirname(__FILE__)) ."/" );
/**
* 引入核心入口
* ThinkPHP亦可移动到WEB以外的目录
*/

//------------!!!在这里引入Composer的autoload!!------------//
require '../../Extends/vendor/autoload.php';
require '../ThinkPHP/ThinkPHP.php';


这是因为ThinkPHP有非常糟糕的引导机制:

index.php  --require--> ThinkPHP.php --require--> Common/runtime.php


这个过程是单线的,穿插大量必要的宏定义,和大量的if逻辑.

最关键的启动代码
Think::Start();
却在
runtime.php
最后一行执行.

这好比把衣服裤子鞋子做成了一件连体服.想要加一根腰带,要么脱光,要么剪开衣服.与其在劈头盖脸的if else中找剪裁点,还是选择脱光吧.

下一节聊聊如何把Laravel的Container组件独立出来
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  thinkphp laravel php IoC