zoukankan      html  css  js  c++  java
  • 当PHP引擎试图实例化一个未知类的操作

    在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机制进行加载。

  • 相关阅读:
    Json,Gson,FastJson解析笔记
    Java 里把 InputStream 转换成 String 的几种方法
    11大Java开源中文分词器的使用方法和分词效果对比,当前几个主要的Lucene中文分词器的比较
    HDU 1599 find the mincost route
    如何更改Java括号中的默认对齐
    Android Java 与 C++ 恒调用,路径、文件名、延长的最大长度
    使用android SpannableStringBuilder实现图文混排,看到许多其他
    POJ 2352 Stars 树阵
    cocos2dx环境配置和打包
    DSR on Openstack POC
  • 原文地址:https://www.cnblogs.com/cbryge/p/6011096.html
Copyright © 2011-2022 走看看