移植 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的引导文件
没有命名空间,大量关键类同名
引入外部库还要用令人费解的import()方法
生成autoload的代码位置 , 在设计理念上有错
靠ThinkPHP去管理各种现代依赖 , 基本是不可能完成的任务 . 这时Composer就大显身手了.
我们可以在任意文件夹创建
运行
瞥一眼
引入了
引入了按
所以我们只要把
问题是
这是因为ThinkPHP有非常糟糕的引导机制:
这个过程是单线的,穿插大量必要的宏定义,和大量的if逻辑.
最关键的启动代码
这好比把衣服裤子鞋子做成了一件连体服.想要加一根腰带,要么脱光,要么剪开衣服.与其在劈头盖脸的if else中找剪裁点,还是选择脱光吧.
下一节聊聊如何把Laravel的Container组件独立出来
用惯了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组件独立出来
相关文章推荐
- 一个关于if else容易迷惑的问题
- PHP5.2.*防止Hash冲突拒绝服务攻击的Patch
- 深入理解PHP之匿名函数
- JSP/PHP基于Ajax的分页功能实现
- 关于PHP通过PDO用中文条件查询MySQL的问题。
- 什么是设计模式
- PHP数据库长连接mysql_pconnect的细节
- kindeditor 批量上传 上传失败 thinkphp swfupload session
- Php Installing An Expansion
- workerman结合laravel开发在线聊天应用的示例代码
- 简单对比分析Ruby on Rails 和 Laravel
- PHP+Apache在Windows 9x下的安装和配置
- IIS 6 的 PHP 最佳配置方法
- 安装Apache和PHP的一些补充
- Linux Apache+MySQL+PHP
- 建立Apache+PHP+MySQL数据库驱动的动态网站
- PHP 5.3.0 安装分析心得
- apache 环境下 php 的配置注意事项
- ASP.NET、ASP、PHP、JSP之间有什么区别?