在3.2中,基本上无需手动加载类库文件,你可以很方便的完成自动加载。

命名空间自动加载

系统可以通过类的命名空间自动定位到类库文件,例如:

我们定义了一个类 Org\Util\Auth 类:

  1. namespace Org\Util;
  2. class Auth {
  3. }

保存到 ThinkPHP/Library/Org/Util/Auth.class.php

接下来,我们就可以直接实例化了。

  1. new \Org\Util\Auth();

在实例化Org\Util\Auth类的时候,系统会自动加载 ThinkPHP/Library/Org/Util/Auth.class.php 文件。

框架的Library目录下面的命名空间都可以自动识别和定位,例如:

  1. ├─Library 框架类库目录
  2. │ ├─Think 核心Think类库包目录
  3. │ ├─Org Org类库包目录
  4. │ ├─ ... 更多类库目录

Library目录下面的子目录都是一个根命名空间,也就是说以Think、Org为根命名空间的类都可以自动加载:

  1. new Think\Cache\Driver\File();
  2. new Org\Util\Auth();
  3. new Org\Io\File();

都可以自动加载对应的类库文件。

你可以在Library目录下面任意增加新的目录,就会自动注册成为一个新的根命名空间。

注册新的命名空间

除了Library目录下面的命名空间之外,我们还可以注册其他的根命名空间,例如:

  1. 'AUTOLOAD_NAMESPACE' => array(
  2. 'My' => THINK_PATH.'My',
  3. 'One' => THINK_PATH.'One',
  4. )

配置了上面的AUTOLOAD_NAMESPACE后,如果我们实例化下面的类库

  1. new My\Net\IpLocation();
  2. new One\Util\Log();

会自动加载对应的类库文件

  1. ThinkPHP/My/Net/IpLocation.class.php
  2. ThinkPHP/One/Util/Log.class.php

如果命名空间不在Library目录下面,并且没有定义对应的AUTOLOAD_NAMESPACE参数的话,则会当作模块的命名空间进行自动加载,例如:

  1. new Home\Model\UserModel();
  2. new Home\Event\UserEvent();

由于ThinkPHP/Library目录下面不存在Home目录,也没在AUTOLOAD_NAMESPACE参数定义Home命名空间,所以就把Home当成模块命名空间来识别,所以会自动加载:

  1. Application/Home/Model/UserModel.class.php
  2. Application/Home/Event/UserEvent.class.php

注意:命名空间的大小写需要和目录名的大小写对应,否则可能会自动加载失败。

类库映射

遵循我们上面的命名空间定义规范的话,基本上可以完成类库的自动加载了,但是如果定义了较多的命名空间的话,效率会有所下降,所以,我们可以给常用的类库定义类库映射。命名类库映射相当于给类文件定义了一个别名,效率会比命名空间定位更高效,例如:

  1. Think\Think::addMap('Think\Log',THINK_PATH.'Think\Log.php');
  2. Think\Think::addMap('Org\Util\Array',THINK_PATH.'Org\Util\Array.php');

也可以利用addMap方法批量导入类库映射定义,例如:

  1. $map = array('Think\Log'=>THINK_PATH.'Think\Log.php','Org\Util\Array'=>THINK_PATH.'Org\Util\Array.php');
  2. Think\Think::addMap($map);

当然,比较方便的方式是我们可以在模块配置目录下面创建alias.php文件用于定义类库映射,该文件会自动加载,定义方式如下:

  1. return array(
  2. 'Think\Log' => THINK_PATH.'Think\Log.php',
  3. 'Org\Util\Array' => THINK_PATH.'Org\Util\Array.php'
  4. );

自动加载的优先级

在实际的应用类库加载过程中,往往会涉及到自动加载的优先级问题,以Test\MyClass类为例,自动加载的优先顺序如下:

  1. 判断是否有注册了Test\MyClass类库映射,如果有则自动加载类库映射定义的文件;
  2. 判断是否存在Library/Test目录,有则以该目录为初始目录加载;
  3. 判断是否有注册Test根命名空间,有则以注册的目录为初始目录加载;
  4. 如果以上都不成立,则以Test为模块目录进行初始目录加载;

以上面获取到的初始目录加载命名空间对应路径的文件;

手动加载第三方类库

如果要加载第三方类库,包括不符合命名规范和后缀的类库,以及没有使用命名空间或者命名空间和路径不一致的类库,或者你就是想手动加载类库文件,我们都可以通过手动导入的方式加载。

我们可以使用import方法导入任何类库,用法如下:

  1. // 导入Org类库包 Library/Org/Util/Date.class.php类库
  2. import("Org.Util.Date");
  3. // 导入Home模块下面的 Application/Home/Util/UserUtil.class.php类库
  4. import("Home.Util.UserUtil");
  5. // 导入当前模块下面的类库
  6. import("@.Util.Array");
  7. // 导入Vendor类库包 Library/Vendor/Zend/Server.class.php
  8. import('Vendor.Zend.Server');

对于import方法,系统会自动识别导入类库文件的位置,ThinkPHP可以自动识别的类库包包括Think、Org、Com、Behavior和Vendor包,以及Library目录下面的子目录,如果你在Library目录下面创建了一个Test子目录,并且创建了一个UserTest.class.php类库,那么可以这样导入:

  1. import('Test.UserTest');

其他的就认为是应用类库导入。

注意,如果你的类库没有使用命名空间定义的话,实例化的时候需要加上根命名空间,例如:

  1. import('Test.UserTest');
  2. $test = new \UserTest();

按照系统的规则,import方法是无法导入具有点号的类库文件的,因为点号会直接转化成斜线,例如我们定义了一个名称为User.Info.class.php 的文件的话,采用:

  1. import("Org.User.Info");

方式加载的话就会出现错误,导致加载的文件不是Org/User.Info.class.php 文件,而是Org/User/Info.class.php 文件,这种情况下,我们可以使用:

  1. import("Org.User#Info");

来导入。

大多数情况下,import方法都能够自动识别导入类库文件的位置,如果是特殊情况的导入,需要指定import方法的第二个参数作为起始导入路径。例如,要导入当前文件所在目录下面的 RBAC/AccessDecisionManager.class.php 文件,可以使用:

  1. import("RBAC.AccessDecisionManager",dirname(__FILE__));

如果你要导入的类库文件名的后缀不是class.php而是php,那么可以使用import方法的第三个参数指定后缀:

  1. import("RBAC.AccessDecisionManager",dirname(__FILE__),".php");

注意:在Unix或者Linux主机下面是区别大小写的,所以在使用import方法的时候要注意目录名和类库名称的大小写,否则会导入失败。

如果你的第三方类库都放在Vendor目录下面,并且都以.php为类文件后缀,也没用采用命名空间的话,那么可以使用系统内置的Vendor函数简化导入。 例如,我们把 Zend 的 Filter\Dir.php 放到 Vendor 目录下面,这个时候 Dir 文件的路径就是 Vendor\Zend\Filter\Dir.php,我们使用vendor 方法导入只需要使用:

  1. Vendor('Zend.Filter.Dir');

就可以导入Dir类库了。

Vendor方法也可以支持和import方法一样的基础路径和文件名后缀参数,例如:

  1. Vendor('Zend.Filter.Dir',dirname(__FILE__),'.class.php');

thinkphp 自动加载的更多相关文章

  1. PHP 命名空间与自动加载机制

    include 和 require 是PHP中引入文件的两个基本方法.在小规模开发中直接使用 include 和 require 没哟什么不妥,但在大型项目中会造成大量的 include 和 requ ...

  2. PHP 命名空间与自动加载机制介绍

    include 和 require 是PHP中引入文件的两个基本方法.在小规模开发中直接使用 include 和 require 没哟什么不妥,但在大型项目中会造成大量的 include 和 requ ...

  3. ThinkPHP 3.2.3 自动加载公共函数文件的方法

    方法一.加载默认的公共函数文件 在 ThinkPHP 3.2.3 中,默认的公共函数文件位于公共模块 ./Application/Common 下,访问所有的模块之前都会首先加载公共模块下面的配置文件 ...

  4. thinkphp学习笔记9—自动加载

    原文:thinkphp学习笔记9-自动加载 1.命名空间自动加载 在3.2版本中不需要手动加载类库文件,可以很方便的完成自动加载. 系统可以根据类的命名空间自动定位到类库文件,例如定义了一个类Org\ ...

  5. thinkphp系列:类的自动加载是如何设计的

    在使用框架开发时,可以发现框架有很多核心类,却很少看到显示的引入某个文件的代码,这是因为框架都采用了类的自动加载机制,即使用到类时,框架会自动找到该类所在文件的位置并引入该文件.为了更容易看出代码思路 ...

  6. php自动加载规范 PSR4 (Thinkphp)

    PSR4是一种自动加载规范,老版本是PSR0,尽管thinkPHP支持PSR4和PSR0的自动加载方式,但是默认也是优先进行PSR4加载,如果失败,再进行PSR0的加载.本篇文章只会讨论PSR4的加载 ...

  7. thinkphp线上自动加载异常与修复

    项目遇到一个奇怪的问题,本地代码正常,服务器上却不正常. 经过测试,应该是自动加载出了问题,尝试了各种方法, 1.手动加载,发现好麻烦,没完没了. 2.自己写自动加载,写不出来,尴尬. 3.修改配置, ...

  8. 2)thinkphp的带有命名空间的自动加载机制

    (1)为啥thinkphp里面的文件要是写你的命名空间,要与你的路径一样,因为在thinkphp实现自动加载机制的原理,就是靠的你的命名空间对应这个路径,然后自动加载机制通过这个路径找到你的类文件,然 ...

  9. 关于thinkPHP中的自动加载和手动导入

    首先先讲自动加载: 前提:你的第三方类库要满足(1)符合命名规范和后缀的类库(2)使用命名空间,命名空间和路径一致的类库 (1)在ThinkPHP目录下的library目录下的每一个子目录都是一个根命 ...

随机推荐

  1. VisualStuido中将C#脚本封装打包DLL并调用

    DLL (Dynamic Link Library)---动态链接库 首先了解下使用DLL的优势,程序运行时不用加载所有代码,只有运行到引用时,才从DLL库中取出.并且使用DLL文件还可以减小程序体积 ...

  2. 要素选择变化事件 IActiveViewEvents_SelectionChanged

    void IDockableWindowDef.OnCreate(object hook) { m_application = hook as IApplication; m_hookHelper = ...

  3. Markdown测试2

    四级标题 内容测试 内容测试 内容测试 为知笔记发布博客时会添加一些HTML或CSS的标记,会影响文章的摘要显示. A B 一 二 α​" role="presentation&q ...

  4. LNMP之PHP

    PHP LNMP环境下的PHP安装 CGI指的是通用网关接口,为HTTP服务器与其他机器上的程序服务通信交流的一种工具,性能差,所以被淘汰了. FastCGI,是一个可以伸缩.高速的在HTTP服务器和 ...

  5. pyJWT

    现在用JWT 加密太火了,怎么能不跟上潮流?否则销售都不好意思出去吹牛逼! PyJWT是一个Python库,用来编码/解码JWT(JSON Web Token)的 1.定义:根据维基百科的定义,JSO ...

  6. python cv2 恢复手机图片

    找到可以恢复的手机图片 矩阵相乘 mat() {} 量化表 8*8 矩阵 与     2 4 2   2    16 16 16后面都是16的8*8矩阵相乘 计算变化的位是否可恢复 单独一张jpg的计 ...

  7. exports和module.exports的区别——学习笔记

    一开始,exports和module.exports都指向空对象(同一内存块),exports是引用 module.exports的值.module.exports 被改变的时候,exports不会被 ...

  8. Java判断链表是否为回文链表

    请判断一个链表是否为回文链表. 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 思路:1.通过快慢指针,来遍历链表 ...

  9. Zabbix-server及zabbix-web安装手册(centos7)

    注:本实验环境在centos7mini下实验,具体相关软件版本最好一致,避免依赖关系缺失. 当然也可以新建用户zabbix(不使用root,避免安全隐患),在zabbix下执行操作,加sudo提升权限 ...

  10. NX二次开发-将对象移动到图层UF_OBJ_set_layer

    #include <uf.h> #include <uf_obj.h> #include <uf_modl.h> #include <uf_layer.h&g ...