php自动加载机制的深入分析


Posted in PHP onJune 08, 2013

一、php中实现自动加载的方法
1.使用require,include,require_once,include_once手工进行加载。
2.使用__autoload来进行自动加载
3.使用spl的autoload来实现自动加载
手工加载的实现:

当需要加载的文件很少的时候我们可以使用第一个来完成。这样做很简单也没问题。

require_once 'a.php';
require_once 'b.php';
require_once 'c.php';

但是当需要加载文件很多的时候这样做还行吗?需要写十个,二十个require_once 或者更多的时候我们该怎么办?

这个时候我们可以使用__autoload方法来简化我们的代码。

__autoload加载的实现:
我们在test目录下创建一个in.php文件,内容如下。

echo '我是test下面的in.php<br />';

然后在test目录下创建一个loader.php,内容如下。
// 需要重载__autoload方法,自定义包含类文件的路径  
function __autoload($classname)  
{  
 $class_file = strtolower($classname).".php";  
 if (file_exists($class_file)){  
  require_once($class_file);  
 }  
}
@$test = new in(); // 执行到这里会输出 <SPAN style="FONT-FAMILY: Arial, Helvetica, sans-serif">我是test下面的in.php</SPAN>

没问题,成功了!我们还可以创建其他的文件来进行加载,但是当需要的文件很多需要区分目录的时候怎么办?

这时我们需要修改loader.php可以使用映射来找到要加载的文件。

function __autoload($class_name) {
 $map = array(
  'index' => './include/index.php',
  'in' => './in.php'
 );
    if (file_exists($map[$class_name]) && isset($map[$class_name])) {
        require_once $map[$class_name];
    }
}
new index();

这种方法的好处就是类名和文件路径只是用一个映射来维护,所以当文件结构改变的时候,不需要修改类名,只需要将映射中对应的项修改就好了。

但是__autoload在一个项目中只能使用一次,当你的项目引用了别人的一个项目,你的项目中有一个__autoload,别人的项目也有一个__autoload,这样两个__autoload就冲突了.解决的办法就是修改__autoload成为一个,这无疑是非常繁琐的,应用场景单一。

spl的autoload加载实现:
spl的autoload系列函数使用一个autoload调用堆栈,你可以使用spl_autoload_register注册多个自定义的autoload函数,应用场景广泛

php自动加载机制的深入分析

•在test目录下建立in.php,内容如下  

<?php
class in {
 public function index() {
  echo '我是test下面的in.php';
 }
}
?>

在test目录下建立loader.php,内容如下
<?php
set_include_path("/var/www/test/"); //这里需要将路径放入include
spl_autoload("in"); //寻找/var/www/test/in.php
$in = new in();
$in->index();

•spl_autoload_register将函数注册到SPL __autoload函数栈中,修改loader.php
function AutoLoad($class){
    if($class == 'in'){
        require_once("/var/www/test/in.php");
    }
}
spl_autoload_register('AutoLoad');
$a = new in();
$a->index();

•spl_autoload_register注册多个自定义的autoload函数的应用
首先在test目录下建立mods文件夹并建立inmod.mod.php内容如下:
<?php
class inmod
{
 function __construct()
 {
  echo '我是mods下的in';
 }
}

然后在test目录下建立libs文件夹并建立inlib.lib.php内容如下:
<?php
class inlib
{
 function __construct()
 {
  echo '我是libs下的in';
 }
}

最后在test目录下建立loader.php内容如下
<?php
class Loader {
    /**
    * 自动加载类
    * @param $class 类名
    */
    public static function mods($class) {
        if($class){
   set_include_path( "/var/www/test/mods/" );
   spl_autoload_extensions( ".mod.php" );
   spl_autoload( strtolower($class) );
        }
    }
    public static function libs($class) {
  if($class){
   set_include_path( "/var/www/test/libs/" );
   spl_autoload_extensions( ".lib.php" );
   spl_autoload( strtolower($class) );
        }
    }
}
spl_autoload_register(array('Loader', 'mods'));
spl_autoload_register(array('Loader', 'libs'));
new inmod();//输出<SPAN style="FONT-FAMILY: 'Times New Roman'; FONT-SIZE: 14px">我是mods下的in</SPAN>
new inlib();//<SPAN style="FONT-FAMILY: Arial, Helvetica, sans-serif">输出</SPAN><SPAN style="FONT-FAMILY: 'Times New Roman'; FONT-SIZE: 14px">我是libs下的in</SPAN>

PHP 相关文章推荐
用Socket发送电子邮件(利用需要验证的SMTP服务器)
Oct 09 PHP
利用discuz自带通行证整合dedecms的方法以及文件下载
Mar 06 PHP
PHP新手NOTICE错误常见解决方法
Dec 07 PHP
php中global和$GLOBALS[]的分析之一
Feb 02 PHP
PHP 验证码不显示只有一个小红叉的解决方法
Sep 30 PHP
php中mkdir函数用法实例分析
Nov 15 PHP
php生成验证码函数
Oct 20 PHP
详解PHP数组赋值方法
Nov 07 PHP
php页面跳转session cookie丢失导致不能登录等问题的解决方法
Dec 12 PHP
PHP下 Mongodb 连接远程数据库的实例代码
Aug 30 PHP
PHP获取链表中倒数第K个节点的方法
Jan 18 PHP
PHP实现获取ip地址的5种方法,以及插入用户登录日志操作示例
Feb 28 PHP
深入理解curl类,可用于模拟get,post和curl下载
Jun 08 #PHP
coreseek 搜索英文的问题详解
Jun 08 #PHP
探讨如何在php168_cms中提取验证码
Jun 08 #PHP
如何使用php绘制在图片上的正余弦曲线
Jun 08 #PHP
基于php常用正则表达式的整理汇总
Jun 08 #PHP
PHP计数器的实现代码
Jun 08 #PHP
使用cookie实现统计访问者登陆次数
Jun 08 #PHP
You might like
PHP Cookei记录用户历史浏览信息的代码
2016/02/03 PHP
php中上传文件的的解决方案
2018/09/25 PHP
Node调试工具JSHint的安装及配置教程
2014/05/27 Javascript
nodejs中的fiber(纤程)库详解
2015/03/24 NodeJs
JS动态修改图片的URL(src)的方法
2015/04/01 Javascript
JavaScript将当前时间转换成UTC标准时间的方法
2015/04/06 Javascript
JavaScript实现将UPC转换成ISBN的方法
2015/05/26 Javascript
详解JavaScript中void语句的使用
2015/06/04 Javascript
json传值以及ajax接收详解
2016/05/24 Javascript
js获取form表单所有数据的简单方法
2016/08/18 Javascript
AngularJS中如何使用echart插件示例详解
2016/10/26 Javascript
jquery实现轮播图效果
2017/02/13 Javascript
微信小程序实战之自定义抽屉菜单(7)
2017/04/18 Javascript
详解小程序不同页面之间通讯的解决方案
2018/11/23 Javascript
区分vue-router的hash和history模式
2020/10/03 Javascript
详解 javascript对象创建模式
2020/10/30 Javascript
[01:20:38]完美世界DOTA2联赛 GXR vs IO 第一场 11.07
2020/11/09 DOTA
python通过装饰器检查函数参数数据类型的方法
2015/03/13 Python
在Python的Flask框架中使用日期和时间的教程
2015/04/21 Python
Python中列表的一些基本操作知识汇总
2015/05/20 Python
python实现数据图表
2017/07/29 Python
python 获取等间隔的数组实例
2019/07/04 Python
Django实现文件上传下载功能
2019/10/06 Python
Python 下载及安装详细步骤
2019/11/04 Python
CSS3近阶段篇之酷炫的3D旋转透视
2016/04/28 HTML / CSS
基于Modernizr 让网站进行优雅降级的分析
2013/04/21 HTML / CSS
Jimmy Choo美国官网:周仰杰鞋子品牌
2018/06/08 全球购物
SportsDirect.com新加坡:英国第一体育零售商
2019/03/30 全球购物
给老师的检讨书
2014/02/11 职场文书
护士长竞聘演讲稿
2014/04/30 职场文书
事业单位年度考核个人总结
2015/02/12 职场文书
杨善洲观后感
2015/06/04 职场文书
网吧员工管理制度
2015/08/05 职场文书
中秋节主题班会
2015/08/14 职场文书
通知怎么写?
2019/04/17 职场文书
用Python监控你的朋友都在浏览哪些网站?
2021/05/27 Python