在PHP开发过程中,如果希望从外部引入一个class,通常会使用include和require方法,去把定义这个class的文件包含进来,但是这样可能会使得在引用文件的新脚本中,存在大量的include或require方法调用,如果一时疏忽遗漏则会产生错误,使得代码难以维护。

自PHP5后,引入了__autoload这个拦截器方法,可以自动对class文件进行包含引用,通常我们会这么写: 
复制代码 代码如下:
function __autoload($className) { 
include_once $className . '.class.php'; 
}

$user = new User();

当PHP引擎试图实例化一个未知类的操作时,会调用__autoload()方法,在PHP出错失败前有了最后一个机会加载所需的类。因此,上面的这段代码执行时,PHP引擎实际上替我们自动执行了一次__autoload方法,将User.class.php这个文件包含进来。

在__autoload函数中抛出的异常不能被catch语句块捕获并导致致命错误。

如果使用 PHP的CLI交互模式时,自动加载机制将不会执行。

当你希望使用PEAR风格的命名规则,例如需要引入User/Register.php文件,也可以这么实现: 
复制代码 代码如下:
//加载我 
function __autoload($className) { 
$file = str_replace('_', DIRECTORY_SEPARATOR, $className); 
include_once $file . 'php'; 

$userRegister = new User_Register();

这种方法虽然方便,但是在一个大型应用中如果引入多个类库的时候,可能会因为不同类库的autoload机制而产生一些莫名其妙的问题。在PHP5引入SPL标准库后,我们又多了一种新的解决方案,spl_autoload_register()函数。

此函数的功能就是把函数注册至SPL的__autoload函数栈中,并移除系统默认的__autoload()函数。一旦调用spl_autoload_register()函数,当调用未定义类时,系统会按顺序调用注册到spl_autoload_register()2881064151函数的所有函数,而不是自动调用__autoload()函数,下例调用的是User/Register.php而不是User_Register.class.php: 
复制代码 代码如下:
//不加载我 
function __autoload($className) { 
include_once $className . '.class.php'; 

//加载我 
function autoload($className) { 
$file = str_replace('/', DIRECTORY_SEPARATOR, $className); 
include_once $file . '.php'; 

//开始加载 
spl_autoload_register('autoload'); 
$userRegister = new User_Register();

在使用spl_autoload_register()的时候,我们还可以考虑采用一种更安全的初始化调用方法,参考如下: 
复制代码 代码如下:
//系统默认__autoload函数 
function __autoload($className) { 
include_once $className . '.class.php'; 

//可供SPL加载的__autoload函数 
function autoload($className) { 
$file = str_replace('_', DIRECTORY_SEPARATOR, $className); 
include_once $file . '.php'; 

//不小心加载错了函数名,同时又把默认__autoload机制给取消了……
spl_autoload_register('_autoload', false); 
//容错机制 
if(false === spl_autoload_functions()) { 
if(function_exists('__autoload')) { 
spl_autoload_register('__autoload', false); 

}

奇技淫巧:在Unix/Linux环境下,如果你有多个规模较小的类,为了管理方便,都写在一个php文件中的时候,可以通过以ln -s命令做软链接的方式快速分发成多个不同类名的拷贝,再通过autoload机制进行加载。

当PHP引擎试图实例化一个未知类的操作的更多相关文章

  1. 如何利用AI识别未知——加入未知类(不太靠谱),检测待识别数据和已知样本数据的匹配程度(例如使用CNN降维,再用knn类似距离来实现),将问题转化为特征搜索问题而非决策问题,使用HTM算法(记忆+模式匹配预测就是智能),GAN异常检测,RBF

    https://www.researchgate.net/post/How_to_determine_unknown_class_using_neural_network 里面有讨论,说是用rbf神经 ...

  2. 定义一个Person类,其中包括:1.定义属性:姓名、年龄、民族作为成员变量。定义静态成员变量:人数2.定义构造方法:对成员变量进行初始化。3.定义多个方法:分别显示相应的属性值,例如getName(){System.out.print("名称="+name+";"); }4.定义一个方法“成长”:实现年龄的增加,每执行一次年龄增加1

    题目显示不全,完整题目描述: (1)定义一个Person类,其中包括:1.定义属性:姓名:年龄:民族作为成员变量.定义静态成员变量:人数2.定义构造方法:对成员变量进行初始化.3.定义多个方法:分别显 ...

  3. PHP用单例模式实现一个数据库类

    使用单例模式的出发点: 1.php的应用主要在于数据库应用, 所以一个应用中会存在大量的数据库操作, 使用单例模式, 则可以避免大量的new 操作消耗的资源. 2.如果系统中需要有一个类来全局控制某些 ...

  4. PHP加载另一个文件类的方法

    加载另一个文件类的方法 当前文件下有a.php 和b.php,想要在class b中引入class a <?php    class a    {        public $name = ' ...

  5. T4教程2 T4模版引擎之生成数据库实体类

    T4模版引擎之生成数据库实体类   在通过T4模版引擎之基础入门 对T4有了初步印象后,我们开始实战篇.T4模板引擎可以当做一个代码生成器,代码生成器的职责当然是用来生成代码(这不是废话吗).而这其中 ...

  6. [百度空间] [原]DLL导出实例化的模板类

    因为模板是在编译的时候根据模板参数实例化的,实例化之后就像一个普通的类(函数),这样才有对应的二进制代码;否则,没有模板参数,那么编译器就不知道怎么生成代码,所以生成的DLL就没有办法导出模板了.但是 ...

  7. [转]T4模版引擎之生成数据库实体类

    本文转自:http://www.cnblogs.com/lzrabbit/archive/2012/07/18/2597953.html 在通过T4模版引擎之基础入门 对T4有了初步印象后,我们开始实 ...

  8. Class撑起了OOP世界的天。Class类是OO的基本单元,OO的世界都是通过一个一个的类协作完成的,提高软件的重用性、灵活性和扩展性(转)

    引言 在OO的工作中,我们一定会涉及到类,抽象类和接口.那么类和抽象类以及接口到底扮演的什么角色? 本文主要是从人类社会的角度阐述类与抽象类以及接口的“社会”关系,从而让我们抛弃书上的那些死记硬背的概 ...

  9. T4模版引擎之生成数据库实体类

    在通过T4模版引擎之基础入门 对T4有了初步印象后,我们开始实战篇.T4模板引擎可以当做一个代码生成器,代码生成器的职责当然是用来生成代码(这不是废话吗).而这其中我们使用的最普遍的是根据数据库生成实 ...

随机推荐

  1. codeforces A. Group of Students 解题报告

    题目链接:http://codeforces.com/problemset/problem/357/A 题目意思:将一堆人分成两组:beginners 和 intermediate coders .每 ...

  2. poj 3750 小孩报数问题 解题报告

    题目链接:http://poj.org/problem?id=3750 约瑟夫问题,直接模拟即可. #include <iostream> #include <string> ...

  3. 双系统重装windows后修复UBUNTU的GRUB

    1.问题背景 本子是win7和ubuntu10.04双系统,用的还算好,虽然只有在用QQ的时候还会用到win7,但还是保留windows.可是几天 前,win7突然总是蓝屏.死机,更重要是的背景变成黑 ...

  4. Java Hour 18 来个CURD吧 (三)

    有句名言,叫做10000小时成为某一个领域的专家.姑且不辩论这句话是否正确,让我们到达10000小时的时候再回头来看吧. 本文作者Java 现经验约为18 Hour,请各位不吝赐教. 依赖Jar 包管 ...

  5. 实例讲解虚拟机3种网络模式(桥接、nat、Host-only)

    转自:http://www.cnblogs.com/ggjucheng/archive/2012/08/19/2646007.html 前言 很多人安装虚拟机的时候,经常遇到不能上网的问题,而vmwa ...

  6. ServletContext中常用方法(getRsource和getResourceAsStream)

    转自:http://blog.csdn.net/yakson/article/details/9203267 一..获取Tomcat的Context的初始化参数. 1.获取Tomcat的server. ...

  7. Android中的.9.png

      智能手机中经常有自动横屏的功能,同一幅界面在随着手机(或平板电脑)中的方向传感器会改变显示的方向,在界面改变方向后,界面上的图形会因为长宽的变化产生拉伸,造成图形的变形.例如下面一个在竖屏时正常显 ...

  8. Grunt上手指南<转>

    原文链接:http://www.hulufei.com/post/grunt-introduction 安装 如果之前有装过grunt,卸载之 npm uninstall -g grunt 安装gru ...

  9. 指示灯组与3个复位按钮的介绍Arduino Yun快速入门教程

    指示灯组与3个复位按钮的介绍Arduino Yun快速入门教程 1.4.2  指示灯组 指示灯组的放大图如图1.5所示. 图1.5  指示灯组 各个指示灯对应的功能如下: q  RX:对应于0号端口, ...

  10. 转-CSS3 圆角(border-radius)

    CSS3 圆角(border-radius)   前缀 例1 例2:无边框 书写顺序 其它 支持性 值:半径的长度 前缀 -moz(例如 -moz-border-radius)用于Firefox -w ...