thinkphp 自动加载
在3.2中,基本上无需手动加载类库文件,你可以很方便的完成自动加载。
命名空间自动加载
系统可以通过类的命名空间自动定位到类库文件,例如:
我们定义了一个类 Org\Util\Auth
类:
namespace Org\Util;
class Auth {
}
保存到 ThinkPHP/Library/Org/Util/Auth.class.php
。
接下来,我们就可以直接实例化了。
new \Org\Util\Auth();
在实例化Org\Util\Auth
类的时候,系统会自动加载 ThinkPHP/Library/Org/Util/Auth.class.php
文件。
框架的Library目录下面的命名空间都可以自动识别和定位,例如:
├─Library 框架类库目录
│ ├─Think 核心Think类库包目录
│ ├─Org Org类库包目录
│ ├─ ... 更多类库目录
Library目录下面的子目录都是一个根命名空间,也就是说以Think、Org为根命名空间的类都可以自动加载:
new Think\Cache\Driver\File();
new Org\Util\Auth();
new Org\Io\File();
都可以自动加载对应的类库文件。
你可以在Library目录下面任意增加新的目录,就会自动注册成为一个新的根命名空间。
注册新的命名空间
除了Library目录下面的命名空间之外,我们还可以注册其他的根命名空间,例如:
'AUTOLOAD_NAMESPACE' => array(
'My' => THINK_PATH.'My',
'One' => THINK_PATH.'One',
)
配置了上面的AUTOLOAD_NAMESPACE
后,如果我们实例化下面的类库
new My\Net\IpLocation();
new One\Util\Log();
会自动加载对应的类库文件
ThinkPHP/My/Net/IpLocation.class.php
ThinkPHP/One/Util/Log.class.php
如果命名空间不在Library目录下面,并且没有定义对应的AUTOLOAD_NAMESPACE
参数的话,则会当作模块的命名空间进行自动加载,例如:
new Home\Model\UserModel();
new Home\Event\UserEvent();
由于ThinkPHP/Library目录下面不存在Home目录,也没在AUTOLOAD_NAMESPACE
参数定义Home命名空间,所以就把Home当成模块命名空间来识别,所以会自动加载:
Application/Home/Model/UserModel.class.php
Application/Home/Event/UserEvent.class.php
注意:命名空间的大小写需要和目录名的大小写对应,否则可能会自动加载失败。
类库映射
遵循我们上面的命名空间定义规范的话,基本上可以完成类库的自动加载了,但是如果定义了较多的命名空间的话,效率会有所下降,所以,我们可以给常用的类库定义类库映射。命名类库映射相当于给类文件定义了一个别名,效率会比命名空间定位更高效,例如:
Think\Think::addMap('Think\Log',THINK_PATH.'Think\Log.php');
Think\Think::addMap('Org\Util\Array',THINK_PATH.'Org\Util\Array.php');
也可以利用addMap方法批量导入类库映射定义,例如:
$map = array('Think\Log'=>THINK_PATH.'Think\Log.php','Org\Util\Array'=>THINK_PATH.'Org\Util\Array.php');
Think\Think::addMap($map);
当然,比较方便的方式是我们可以在模块配置目录下面创建alias.php文件用于定义类库映射,该文件会自动加载,定义方式如下:
return array(
'Think\Log' => THINK_PATH.'Think\Log.php',
'Org\Util\Array' => THINK_PATH.'Org\Util\Array.php'
);
自动加载的优先级
在实际的应用类库加载过程中,往往会涉及到自动加载的优先级问题,以Test\MyClass
类为例,自动加载的优先顺序如下:
- 判断是否有注册了Test\MyClass类库映射,如果有则自动加载类库映射定义的文件;
- 判断是否存在Library/Test目录,有则以该目录为初始目录加载;
- 判断是否有注册Test根命名空间,有则以注册的目录为初始目录加载;
- 如果以上都不成立,则以Test为模块目录进行初始目录加载;
以上面获取到的初始目录加载命名空间对应路径的文件;
手动加载第三方类库
如果要加载第三方类库,包括不符合命名规范和后缀的类库,以及没有使用命名空间或者命名空间和路径不一致的类库,或者你就是想手动加载类库文件,我们都可以通过手动导入的方式加载。
我们可以使用import方法导入任何类库,用法如下:
// 导入Org类库包 Library/Org/Util/Date.class.php类库
import("Org.Util.Date");
// 导入Home模块下面的 Application/Home/Util/UserUtil.class.php类库
import("Home.Util.UserUtil");
// 导入当前模块下面的类库
import("@.Util.Array");
// 导入Vendor类库包 Library/Vendor/Zend/Server.class.php
import('Vendor.Zend.Server');
对于import方法,系统会自动识别导入类库文件的位置,ThinkPHP可以自动识别的类库包包括Think、Org、Com、Behavior和Vendor包,以及Library目录下面的子目录,如果你在Library目录下面创建了一个Test子目录,并且创建了一个UserTest.class.php类库,那么可以这样导入:
import('Test.UserTest');
其他的就认为是应用类库导入。
注意,如果你的类库没有使用命名空间定义的话,实例化的时候需要加上根命名空间,例如:
import('Test.UserTest');
$test = new \UserTest();
按照系统的规则,import方法是无法导入具有点号的类库文件的,因为点号会直接转化成斜线,例如我们定义了一个名称为User.Info.class.php 的文件的话,采用:
import("Org.User.Info");
方式加载的话就会出现错误,导致加载的文件不是Org/User.Info.class.php 文件,而是Org/User/Info.class.php 文件,这种情况下,我们可以使用:
import("Org.User#Info");
来导入。
大多数情况下,import方法都能够自动识别导入类库文件的位置,如果是特殊情况的导入,需要指定import方法的第二个参数作为起始导入路径。例如,要导入当前文件所在目录下面的 RBAC/AccessDecisionManager.class.php 文件,可以使用:
import("RBAC.AccessDecisionManager",dirname(__FILE__));
如果你要导入的类库文件名的后缀不是class.php而是php,那么可以使用import方法的第三个参数指定后缀:
import("RBAC.AccessDecisionManager",dirname(__FILE__),".php");
注意:在Unix或者Linux主机下面是区别大小写的,所以在使用import方法的时候要注意目录名和类库名称的大小写,否则会导入失败。
如果你的第三方类库都放在Vendor目录下面,并且都以.php为类文件后缀,也没用采用命名空间的话,那么可以使用系统内置的Vendor函数简化导入。 例如,我们把 Zend 的 Filter\Dir.php 放到 Vendor 目录下面,这个时候 Dir 文件的路径就是 Vendor\Zend\Filter\Dir.php,我们使用vendor 方法导入只需要使用:
Vendor('Zend.Filter.Dir');
就可以导入Dir类库了。
Vendor方法也可以支持和import方法一样的基础路径和文件名后缀参数,例如:
Vendor('Zend.Filter.Dir',dirname(__FILE__),'.class.php');
thinkphp 自动加载的更多相关文章
- PHP 命名空间与自动加载机制
include 和 require 是PHP中引入文件的两个基本方法.在小规模开发中直接使用 include 和 require 没哟什么不妥,但在大型项目中会造成大量的 include 和 requ ...
- PHP 命名空间与自动加载机制介绍
include 和 require 是PHP中引入文件的两个基本方法.在小规模开发中直接使用 include 和 require 没哟什么不妥,但在大型项目中会造成大量的 include 和 requ ...
- ThinkPHP 3.2.3 自动加载公共函数文件的方法
方法一.加载默认的公共函数文件 在 ThinkPHP 3.2.3 中,默认的公共函数文件位于公共模块 ./Application/Common 下,访问所有的模块之前都会首先加载公共模块下面的配置文件 ...
- thinkphp学习笔记9—自动加载
原文:thinkphp学习笔记9-自动加载 1.命名空间自动加载 在3.2版本中不需要手动加载类库文件,可以很方便的完成自动加载. 系统可以根据类的命名空间自动定位到类库文件,例如定义了一个类Org\ ...
- thinkphp系列:类的自动加载是如何设计的
在使用框架开发时,可以发现框架有很多核心类,却很少看到显示的引入某个文件的代码,这是因为框架都采用了类的自动加载机制,即使用到类时,框架会自动找到该类所在文件的位置并引入该文件.为了更容易看出代码思路 ...
- php自动加载规范 PSR4 (Thinkphp)
PSR4是一种自动加载规范,老版本是PSR0,尽管thinkPHP支持PSR4和PSR0的自动加载方式,但是默认也是优先进行PSR4加载,如果失败,再进行PSR0的加载.本篇文章只会讨论PSR4的加载 ...
- thinkphp线上自动加载异常与修复
项目遇到一个奇怪的问题,本地代码正常,服务器上却不正常. 经过测试,应该是自动加载出了问题,尝试了各种方法, 1.手动加载,发现好麻烦,没完没了. 2.自己写自动加载,写不出来,尴尬. 3.修改配置, ...
- 2)thinkphp的带有命名空间的自动加载机制
(1)为啥thinkphp里面的文件要是写你的命名空间,要与你的路径一样,因为在thinkphp实现自动加载机制的原理,就是靠的你的命名空间对应这个路径,然后自动加载机制通过这个路径找到你的类文件,然 ...
- 关于thinkPHP中的自动加载和手动导入
首先先讲自动加载: 前提:你的第三方类库要满足(1)符合命名规范和后缀的类库(2)使用命名空间,命名空间和路径一致的类库 (1)在ThinkPHP目录下的library目录下的每一个子目录都是一个根命 ...
随机推荐
- D2D
layout category title permalink posts_by_category D2D 渲染相关 /post/D2D.html
- cross compile vlc 播放器
上一篇文章介绍了如何交叉编译 FFmpeg ,继续介绍 VLC播放器 交叉编译 . 首先下载 vlc 源码 我用的是 2.2.6 地址 : http://mirrors.neusoft.edu ...
- 笔记53 Mybatis快速入门(四)
动态SQL 1.if 假设需要对Product执行两条sql语句,一个是查询所有,一个是根据名称模糊查询.那么按照现在的方式,必须提供两条sql语句:listProduct和listProductBy ...
- java.sql.Date和java.util.Date的联系和区别
1) java.sql.Date是java.util.Date的子类,是一个包装了毫秒值的瘦包装器,允许 JDBC 将毫秒值标识为 SQL DATE 值.毫秒值表示自 1970 年 1 月 1 日 0 ...
- Dubbo支持的注册中心有哪些?
1.Dubbo协议(官方推荐协议) 优点: 采用NIO复用单一长连接,并使用线程池并发处理请求,减少握手和加大并发效率,性能较好(推荐使用) 缺点: 大文件上传时,可能出现问题(不使用Dubbo文件上 ...
- 单向连通图 Going from u to v or from v to u? poj2762
http://poj.org/problem?id=2762 强连通求子图和子图关系 + 子图关系是链式结构 #include <cstdio> #include <cstdlib& ...
- leetcood学习笔记-39-组合总和
题目描述: 方法一: class Solution: def combinationSum(self, candidates, target): """ :type ca ...
- NX二次开发-UFUN获取点在面上的向量方向UF_MODL_ask_face_props【转载】
1 NX11+VS2013 2 3 4 #include <uf.h> 5 #include <uf_ui.h> 6 #include <uf_modl.h> 7 ...
- NX二次开发-将信息窗口中的文本保存到文本文件中UF_UI_save_listing_window
#include <uf.h> #include <uf_ui.h> UF_initialize(); //打开信息窗口 UF_UI_open_listing_window() ...
- JS中 reduce() 的用法
过去有很长一段时间,我一直很难理解 reduce() 这个方法的具体用法,平时也很少用到它.事实上,如果你能真正了解它的话,其实在很多地方我们都可以用得上,那么今天我们就来简单聊聊JS中 reduce ...