(转)详解spl_autoload_register()函数

news/2024/6/18 18:53:44 标签: php

看到一篇不错的博文,转载过来,可以通过这个自动加载函数spl_autoload_register()来理解PHP的类自动加载原理。

在了解这个函数之前先来看另一个函数:__autoload

一、__autoload

这是一个自动加载函数,在PHP5中,当我们实例化一个未定义的类时,就会触发此函数。看下面例子:

printit.class.php 
 
<?php 
 
class PRINTIT { 
 
 function doPrint() {
  echo 'hello world';
 }
}
?> 
 
index.php 
 
<?
function __autoload( $class ) {
 $file = $class . '.class.php';  
 if ( is_file($file) ) {  
  require_once($file);  
 }
} 
 
$obj = new PRINTIT();
$obj->doPrint();
?>

运行index.php后正常输出hello world。在index.php中,由于没有包含printit.class.php,在实例化printit时,自动调用__autoload函数,参数$class的值即为类名printit,此时printit.class.php就被引进来了。

在面向对象中这种方法经常使用,可以避免书写过多的引用文件,同时也使整个系统更加灵活。

二、spl_autoload_register()

再看 spl_autoload_register(),这个函数与__autoload有与曲同工之妙,看个简单的例子:

<?
function loadprint( $class ) {
 $file = $class . '.class.php';  
 if (is_file($file)) {  
  require_once($file);  
 } 
} 
 
spl_autoload_register( 'loadprint' ); 
 
$obj = new PRINTIT();
$obj->doPrint();
?>

将__autoload换成loadprint函数。但是loadprint不会像__autoload自动触发,这时spl_autoload_register()就起作用了,它告诉PHP碰到没有定义的类就执行loadprint()。

spl_autoload_register() 调用静态方法

<? 
 
class test {
 public static function loadprint( $class ) {
  $file = $class . '.class.php';  
  if (is_file($file)) {  
   require_once($file);  
  } 
 }
} 
 
spl_autoload_register(  array('test','loadprint')  );
//另一种写法:spl_autoload_register(  "test::loadprint"  ); 
 
$obj = new PRINTIT();
$obj->doPrint();
?>

小结:实例化时__autoload会被自动触发该函数, 如果没有执行的对象时,就会执行spl_autoload_register该方法。

三、composer类自动加载研究

vendor/autoload.php

<?php

// autoload.php @generated by Composer

require_once __DIR__ . '/composer/autoload_real.php';

return ComposerAutoloaderInit83cb48187cf44a304a7a6be5e700ede3::getLoader();

autoload_real.php

<?php

// autoload_real.php @generated by Composer

class ComposerAutoloaderInit83cb48187cf44a304a7a6be5e700ede3
{
    private static $loader;

    public static function loadClassLoader($class)
    {
        if ('Composer\Autoload\ClassLoader' === $class) {
            require __DIR__ . '/ClassLoader.php';
        }
    }

    public static function getLoader()
    {
        if (null !== self::$loader) {
            return self::$loader;
        }

        spl_autoload_register(array('ComposerAutoloaderInit83cb48187cf44a304a7a6be5e700ede3', 'loadClassLoader'), true, true);
        self::$loader = $loader = new \Composer\Autoload\ClassLoader();
        spl_autoload_unregister(array('ComposerAutoloaderInit83cb48187cf44a304a7a6be5e700ede3', 'loadClassLoader'));

        $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
        if ($useStaticLoader) {
            require_once __DIR__ . '/autoload_static.php';

            call_user_func(\Composer\Autoload\ComposerStaticInit83cb48187cf44a304a7a6be5e700ede3::getInitializer($loader));
        } else {
            $map = require __DIR__ . '/autoload_namespaces.php';
            foreach ($map as $namespace => $path) {
                $loader->set($namespace, $path);
            }

            $map = require __DIR__ . '/autoload_psr4.php';
            foreach ($map as $namespace => $path) {
                $loader->setPsr4($namespace, $path);
            }

            $classMap = require __DIR__ . '/autoload_classmap.php';
            if ($classMap) {
                $loader->addClassMap($classMap);
            }
        }

        $loader->register(true);

        return $loader;
    }
}

http://www.niftyadmin.cn/n/1383228.html

相关文章

用经验诠释Access、Trunk和Hybird端口数据收发规则

以下内容摘自正在当当网、京东网、卓越网、互动出版网预售&#xff0c;即将正式发售的《华为交换机学习指南》一书&#xff08;全书近千页&#xff09;。本书是由华为官方授权&#xff0c;国内第一本&#xff0c;也是唯一一本华为交换机权威学习指南&#xff0c;是华为ICT认证培…

使用Formik轻松开发更高质量的React表单(三)Formik /解析

提醒和建议 根据我的粗浅经验&#xff0c;如果您对Formik感兴趣&#xff0c;并且想深入学习与使用这个库&#xff0c;我建议您还是先对redux-form的使用逻辑与有关概念有所了解&#xff0c;而且理解和使用方面也变得容易得多的多。因为Formik中许多概念与形式与redux-form极其类…

TP框架怎么打印SQL

TP框架&#xff08;ThinkPHP框架&#xff09;是一个使用PHP语言编写的开源Web应用框架&#xff0c;它提供了一系列快捷简单的方法&#xff0c;方便PHP开发人员快速构建Web应用程序。如果想要在TP框架中打印SQL语句&#xff0c;可以通过以下几种方式&#xff1a; 在数据库配置文…

String类的直接赋值和构造方法赋值的区别

直接赋值&#xff1a;只开辟一块堆内存空间&#xff0c;而且保存的字符串可以自动入池&#xff0c;以供其他内容相同的字符串对象使用。 构造方法&#xff1a;开辟两块堆内存空间&#xff0c;有一块成为垃圾&#xff0c;并且字符串的内容无法自动入池&#xff0c;但是可以使用S…

listen--监听数量

listen--监听数量 #include <sys/socket.h> int listen(int sockfd, int backlog); /* backlog指定了该套接口排队的最大连接个数 */ 调用listen导致套接口从CLOSED状态转换到LISTEN状态。 监听窗口维持两个队列(队列的大小与backlog有关)&#xff1a; 未完成队列&#x…

Spring Cloud 微服务框架使用快速掌握及源码分析

2019独角兽企业重金招聘Python工程师标准>>> 一.Spring Cloud 简介 SpringCloud是一个机遇SpringBoot实现的微服务框架开发工具,它为微服务架构中涉及的配置管理,服务治理,断路器,智能路由,微代理,控制总线,全局锁,决策竞选,分布式会话和集群状态管理等操作提供了一…

突破R内存限制的企业级大数据挖掘利器:Microsoft R Server 快速上手

R语言是一款非常优秀的数据挖掘工具&#xff0c;拥有顶尖的数据处理、数据挖掘课数据可视化。是数据从业者必备的一把利器。但是其基于内存的诟病也一直被人所嫌弃&#xff0c;虽然这几年很多优秀的扩展包极大提升了R语言的性能&#xff0c;但是在面对企业级大数据挖掘面前&…

081 关于微信支付的回调Notify_url

一、你一定要有毅力&#xff01;心平气和&#xff0c;慢慢来&#xff01;&#xff08;微信扫码支付PC端&#xff0c;模式二&#xff09; 二、ri&#xff0c;这个一点要仔细读一下&#xff0c;好不好&#xff0c;大胸弟&#xff01;&#xff01;&#xff01;https的改成http&am…