关于thinkphp5.0 rc4.0扩展类库自动与手动加载的问题
2016-08-26 00:32
429 查看
《ThinkPHP5.0完全开发手册》一共提供了三种方式实现扩展类库加载。
下面,我将这三种方式根据实测案例道来:
第一种:自动注册
把类库包放到
其原理是:tp5遵循了
(假设是框架默认目录结构)执行public下的入口文件index.php,会执行到 注册自动加载
\think\Loader::register();而该方法最后会执行自动加载extend目录self::$fallbackDirsPsr4[] = rtrim(EXTEND_PATH, DS);这个EXTEND_PATH常量是在base.php预先定义好的,defined('EXTEND_PATH')
or define('EXTEND_PATH', ROOT_PATH . 'extend' . DS);其相对于入口文件的路径为:../extend/ ,故我们在
f02a
span style="color:rgb(34,34,34);font-family:'Microsoft Yahei', 'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:16px;line-height:27.2px;">目录,然后定义一个
当你在控制器中直接调用时,如:var_dump((new \my\Test())->sayHello());输出结果为:string(5) "hello"。
因此,当我们要变动类库文件目录结构时,例如我们想让my文件夹还有父级目录vendor,只需在入口文件将define('EXTEND_PATH','../extend/vendor/');放到加载框架引导文件require
__DIR__ . '/../thinkphp/start.php';之前,然后将Test.php文件目录结构变成extend/vendor/my/Test.php就ok了。
第一种方法十分简单,个人推荐使用这种方式。因此我把它放在第一个介绍。
第二种方法:修改应用配置文件实现扩展类库自动加载
原理:这种方式是建立命名空间和类库文件路径的映射关系。
修改应用配置文件(默认框架目录结构application/config.php),注意不是惯例管理配置文件thinkphp/convention.php(tp5优先加载惯例配置,后加载应用配置,后加载的配置会覆盖先加载的)。
还是上面那个例子,我们先注释掉入口文件这一行define('EXTEND_PATH','../extend/vendor/');然后运行,你会发现报错信息提示为:Class
'my\Test' not found.
我们修改application/config.php,修改
注册的根命名空间 'root_namespace'=> ['my' => '../extend/vendor/my/',],然后保存在执行!又出现hello了。
这种方式是建立命名空间和类库文件路径的映射关系。
第三种方式:手动注册新的根命名空间
原理:同第二种方法(用例还是extend/vendor/my/Test.php)
但《ThinkPHP5.0完全开发手册》给出的样例绝对不好用的。如下图:
在应用入口文件中添加下面的代码:
当你把上面的配置文件'root_namespace'=>
['my' => '../extend/vendor/my/',],注释掉时,运行肯定报错。其一是默认的框架目录结构extend和application是同一级目录。其二,my的父目录不是extend,而是vendor。
好,你说不对,那我改成
再运行,怎么还是Class 'my\Test' not found。
这里,修改方案有两种。
第一解决办法,你可以将
放在thinkphp/start.php文件内容的中间位置,修改如下:
namespace think;
// ThinkPHP 引导文件
// 加载基础文件
require __DIR__ . '/base.php';
#########中间#########
\think\Loader::addNamespace('my', '../extend/vendor/my/');
// 执行应用
\think\App::run()->send();
第二解决办法,类似TP3.2.2的入口文件index.php,注释掉thinkphp/start.php文件中的\think\Loader::addNamespace('my', '../extend/vendor/my/'); 将\think\App::run()->send();移到index.php文件尾部。修改如下:
define('APP_PATH', __DIR__ . '/../application/');
// 加载框架引导文件
require __DIR__ . '/../thinkphp/start.php';
########################增加的代码
\think\Loader::addNamespace('my', '../extend/vendor/my/');
// 执行应用
\think\App::run()->send();
运行看看,是不是hello有出来了?
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/titter.gif)
发现猫腻没有?应先注册根命名空间my,再来执行应用,这样执行到控制器那里就会根据my命名空间对应的路径找到Test.php了。
官方手册给出错误的例子,实际上是让我们能深入理解整个框架的执行过程!
发现错误,找出错误原因,涨知识,活运用!让我们做一个快乐的程序猿!
下面,我将这三种方式根据实测案例道来:
第一种:自动注册
把类库包放到
EXTEND_PATH目录(
extend,可配置),就可以自动注册对应的命名空间。
其原理是:tp5遵循了
PSR-4自动加载规范,只要类的文件名均以命名空间定义,并且命名空间的路径和类库文件所在路径一致,便可实现自动加载。
(假设是框架默认目录结构)执行public下的入口文件index.php,会执行到 注册自动加载
\think\Loader::register();而该方法最后会执行自动加载extend目录self::$fallbackDirsPsr4[] = rtrim(EXTEND_PATH, DS);这个EXTEND_PATH常量是在base.php预先定义好的,defined('EXTEND_PATH')
or define('EXTEND_PATH', ROOT_PATH . 'extend' . DS);其相对于入口文件的路径为:../extend/ ,故我们在
extend目录下面新增一个
my<
f02a
span style="color:rgb(34,34,34);font-family:'Microsoft Yahei', 'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:16px;line-height:27.2px;">目录,然后定义一个
\my\Test类( 类文件位于
extend/my/Test.php),Test.php文件内容如下:
namespace my; class Test { public function sayHello() { return 'hello'; } }
当你在控制器中直接调用时,如:var_dump((new \my\Test())->sayHello());输出结果为:string(5) "hello"。
因此,当我们要变动类库文件目录结构时,例如我们想让my文件夹还有父级目录vendor,只需在入口文件将define('EXTEND_PATH','../extend/vendor/');放到加载框架引导文件require
__DIR__ . '/../thinkphp/start.php';之前,然后将Test.php文件目录结构变成extend/vendor/my/Test.php就ok了。
第一种方法十分简单,个人推荐使用这种方式。因此我把它放在第一个介绍。
第二种方法:修改应用配置文件实现扩展类库自动加载
原理:这种方式是建立命名空间和类库文件路径的映射关系。
修改应用配置文件(默认框架目录结构application/config.php),注意不是惯例管理配置文件thinkphp/convention.php(tp5优先加载惯例配置,后加载应用配置,后加载的配置会覆盖先加载的)。
还是上面那个例子,我们先注释掉入口文件这一行define('EXTEND_PATH','../extend/vendor/');然后运行,你会发现报错信息提示为:Class
'my\Test' not found.
我们修改application/config.php,修改
注册的根命名空间 'root_namespace'=> ['my' => '../extend/vendor/my/',],然后保存在执行!又出现hello了。
这种方式是建立命名空间和类库文件路径的映射关系。
第三种方式:手动注册新的根命名空间
原理:同第二种方法(用例还是extend/vendor/my/Test.php)
但《ThinkPHP5.0完全开发手册》给出的样例绝对不好用的。如下图:
在应用入口文件中添加下面的代码:
\think\Loader::addNamespace('my','../application/extend/my/');
当你把上面的配置文件'root_namespace'=>
['my' => '../extend/vendor/my/',],注释掉时,运行肯定报错。其一是默认的框架目录结构extend和application是同一级目录。其二,my的父目录不是extend,而是vendor。
好,你说不对,那我改成
\think\Loader::addNamespace('my', '../extend/vendor/my/',);
再运行,怎么还是Class 'my\Test' not found。
这里,修改方案有两种。
第一解决办法,你可以将
\think\Loader::addNamespace('my', '../extend/vendor/my/');
放在thinkphp/start.php文件内容的中间位置,修改如下:
namespace think;
// ThinkPHP 引导文件
// 加载基础文件
require __DIR__ . '/base.php';
#########中间#########
\think\Loader::addNamespace('my', '../extend/vendor/my/');
// 执行应用
\think\App::run()->send();
第二解决办法,类似TP3.2.2的入口文件index.php,注释掉thinkphp/start.php文件中的\think\Loader::addNamespace('my', '../extend/vendor/my/'); 将\think\App::run()->send();移到index.php文件尾部。修改如下:
define('APP_PATH', __DIR__ . '/../application/');
// 加载框架引导文件
require __DIR__ . '/../thinkphp/start.php';
########################增加的代码
\think\Loader::addNamespace('my', '../extend/vendor/my/');
// 执行应用
\think\App::run()->send();
运行看看,是不是hello有出来了?
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/titter.gif)
发现猫腻没有?应先注册根命名空间my,再来执行应用,这样执行到控制器那里就会根据my命名空间对应的路径找到Test.php了。
官方手册给出错误的例子,实际上是让我们能深入理解整个框架的执行过程!
发现错误,找出错误原因,涨知识,活运用!让我们做一个快乐的程序猿!
相关文章推荐
- 07. Yii 2.0 数据库交互 - Query Builder
- PHP性能优化的小技巧
- PHP如何判断远程图片文件是否存在
- mac下使用brew安装php的xdebug扩展
- PHP 中 9 大缓存技术总结
- UNIX时间戳和日期间的转换与计算实例
- php编译安装脚本
- PhpExcel中文帮助手册|PhpExcel使用方法
- PHP实现四种基本排序算法
- php相关配置
- php001-php基本概念
- PHP技巧:提高PHP性能的53个技巧
- php 面向对象
- php 模块编译提示libtool出错
- 搭建FTP环境
- php操作xml
- ThinkPHP在IIS下配置ISAPI伪静态去掉index.php
- 在Ubuntu系统下安装PhpStorm并启动的方法
- Android+ThinkPHP(后台)实现用户登录功能
- [Laravel-Swagger]如何在 Laravel 项目中使用 Swagger