thinkphp学习笔记9—自动加载

原文:thinkphp学习笔记9—自动加载

1.命名空间自动加载

在3.2版本中不需要手动加载类库文件,可以很方便的完成自动加载。

系统可以根据类的命名空间自动定位到类库文件,例如定义了一个类Org\Util\Auth类:

namespace Org\Util;
class Auth {
}

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

这样我们就可以直接实例化了,

new \Org\Util\Auth();

实例化之后系统会自动加载

ThinkPHP/Library/Org/Util/Auth.class.php 

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

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

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

new Think\Cache\Driver\File();
new Org\Util\Auth();
new Org\Io\File();

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

我们还可以在Liberary目录下面任意增加新的目录,就会自动注册成为一个新的根命名空间,如下:

'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目录下面,并且没有定义对应的AUTO_LOADNAMESPACE参数的话则会当做模块的命名空间自动加载,例如

new Home\Model\UserModel();
new Home\Event\UserEvent();

这跳跃有点大,刚才讲的还是Liberary下的命名空间,现在又扯到Application下的。

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

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

这些命名空间貌似都是ThinkPHP\Liberary目录下的,这个目录下的东西一般不会修改的啊,不明白为什么没有说Application目录下的命名空间。

2.类库映射

定义了较多的命名空间效率会有所影响,可以给常用的类库定义类库映射,命名空间映射相当于给类文件定义了一个别名,例如:

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);

文档中依旧没有说明这段应该写在什么地方,是config.php还是入口文件里呢,捉急啊。

3.类库加载的优先级

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

1.判断是否注册了Test\MyClass类库映射,如果有则自动加载类库映射定义的文件,

2.判断是否存在Liberary\Test目录,有则以该目录为初始目录加载

3.判断是否注册了Test根命名空间,有则以注册的目录为初始目录加载

4.以上都不成立则以Test模块模块经行初始目录加载,

 

4.手动加载第三方类库

使用第三方类库的时候可能出现以下情况,不符合ThinkPHP命名空间和后缀,没有使用命名空间或者命名空间和路径不一致,我们可以使用手动导入的方式加载。

我们使用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,以及Liberary目录下的子目录,这不扯犊子啊,Think,Org,Com,Behavior,Vendor就在ThinkPHP\Liberary下,文档中所说的Liberary目录是指那个目录呢?哦,有可能文档中所说的是Liberary目录下自己新建的目录,有可能。

如果在Liberary目录下新建了一个Test目录,并创建了一个UserTest.class.php文件可以这样导入:

import('Test.UserTest');

注意如果没有使用namespace来定义命名空间的话,实例化的时候需要使用根命名空间,如下:

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可以自动识别导入类库文件的位置,特殊情况下需要第二个参数来指定起始导入的路径,例如:要导入当前文件所在目录下的RBAC/AccessDecisionManager.class.php 文件,可以使用import("RBAC.AccessDecisionManager",dirname(__FILE__)); 。 如果要导入的文件后缀不是class.php而是.php,可以使用第三个参数import("RBAC.AccessDecisionManager",dirname(__FILE__),".php");

 

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

Vendor('Zend.Filter.Dir');

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

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

 

感觉高上大的,这些貌似是对系统进行扩展的时候使用的比较多。

 

 

 

 

时间: 2024-12-02 17:10:47

thinkphp学习笔记9—自动加载的相关文章

反射 学习笔记之动态加载类

1 Class.forName("类的全名")不仅表示了类的类类型,还代表了动态加载类 2 编译时刻加载类称之为静态加载,运行时刻加载类是动态加载类 3 new 对象是静态加载类,在编译时刻就需要加载所有的可能使用的类(编译时刻加载) 用Edit写一个reflectDemo2,里面有俩个命令行参数判断的代码word,execl,我们在同一个文件夹下写一个word类不写execl类,我们假如只想运行word不想运行execl,但是很不幸,由于这是静态加载,javacreflectDemo

thinkPHP线上自动加载异常与修复方法实例分析_php实例

本文实例讲述了thinkPHP线上自动加载异常与修复方法.分享给大家供大家参考,具体如下: 项目遇到一个奇怪的问题,本地代码正常,服务器上却不正常. 经过测试,应该是自动加载出了问题,尝试了各种方法, 1.手动加载,发现好麻烦,没完没了. 2.自己写自动加载,写不出来,尴尬. 3.修改配置,使其支持自动加载,发现还是不行. 后来进行调试, 发现本地支持 import('@.ORG.OSS\OssClient'); import('@.ORG.OSS\Core\OssUtil'); 而服务器上,不

ThinkPHP怎样自动加载类库

如下几种情况,ThinkPHP会自动加载: 系统核心文件,如系统基类下的 Think.Core 等文件定义了别名的类库 当前项目的 Action 类和 Model类自动搜索路径下面的类库 利用 ThinkPHP 的自动加载功能,可以自动加载自己常用的类库,而无需使用 import 方法手动导入.上述四种自动加载机制中,可以利用的为第二种(定义别名)和第四种(定义自动搜索路径). 定义类库别名自动加载 系统默认的别名定义文件位于 ThinkPHP系统目录/Common/alias.php ,为便于

Yii2框架自动加载机制学习

Yii2 的自动加载分两部分,一部分是 Composer 的自动加载机制,另一部分是 Yii2 框架自身的自动加载机制. Composer自动加载 对于库的自动加载信息,Composer 生成了一个 vendor/autoload.php 文件.你可以简单的引入这个文件,你会得到一个自动加载的支持. 在之前的文章,入口文件的介绍中,我们可以看到如下内容: // 引入 vendor 中的 autoload.php 文件,会基于 composer 的机制自动加载类require(__DIR__ .

PHP的类自动加载机制的笔记

在PHP5之前,各个PHP框架如果要实现类的自动加载,一般都是按照某种约定自己实现一个遍历目录,自动加载所有符合约定规则的文件的类或函数. 当然,PHP5之前对面向对象的支持并不是太好,类的使用也没有现在频繁. 在PHP5后,当加载PHP类时,如果类所在文件没有被包含进来,或者类名出错,Zend引擎会自动调用__autoload 函数.此函数需要用户自己实现__autoload函数. 在PHP5.1.2版本后,可以使用spl_autoload_register函数自定义自动加载处理函数.当没有调

thinkphp学习笔记4—眼花缭乱的配置

原文:thinkphp学习笔记4-眼花缭乱的配置   1.配置类别 ThinkPHP提供了灵活的全局配置功能,ThinkPHP会依次加载管理配置>项目配置>调试配置>分组配置>扩展配置>动态配置,所以后面的配置权限要大于前面的,因为后面的配置会覆盖前面同名配置,同事会生辰配置缓存文件无需重复解析,减小开销. 惯例配置:在惯例配置内对大多数常用参数进行默认配置,因为惯例配置最先加载,优先级别最低,如果不需要做特殊配置的话,完全可以保持默认值,惯例配置位于ThinkPHP/Con

thinkphp学习笔记5—模块化设计

原文:thinkphp学习笔记5-模块化设计 1.模块结构 完整的ThinkPHP用用围绕模块/控制器/操作设计,并支持多个入口文件盒多级控制.ThinkPHP默认PATHINFO模式,如下: http://serverName/index.php(或者其他应用入口文件)/模块/控制器/操作/[参数名/参数值...] 应用:由同一个入口文件访问的项目称为一个应用,在完整版的代码中就是Application 模块:一个应用下面可以包含多个模块,每个模块对应独立的目录,在完整版的代码中有Admin,

thinkphp学习笔记8—命名空间

原文:thinkphp学习笔记8-命名空间 新版本(3.2)中采用命名空间的方式定义和加载类库文件,解决多个模块之间的冲突问题,并实现了更加高效的自动加载机制. 需要给类库定义所在的命名空间,命名空间的路径和类库文件的目录一致,就可以实现类的自动加载,例如Org\Util\File类的定义为 namespace Org\Util; class File { } 其所在的路径是ThinkPHP/Library/Org/Util/File.class.php,我们实例化该类写法如下: $class

thinkphp学习笔记7—多层MVC

原文:thinkphp学习笔记7-多层MVC ThinkPHP支持多层设计. 1.模型层Model 使用多层目录结构和命名规范来设计多层的model,例如在项目设计中如果需要区分数据层,逻辑层,服务层等不同的模型层可以在模块目录下创建Model,Logic,Service目录,把对用户表的所有模型操作分成3层. 1.Model/UserModel用于定义数据相关的自动验证,自动完成和数据存取接口 2.Logic/UserLogical用于定义用户相关的业务逻辑 3.Service/UserSer