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 相关文章推荐
十天学会php之第一天
Oct 09 PHP
php 上一篇,下一篇文章实现代码与原理说明
May 09 PHP
PHP生成UTF8文件的方法
May 15 PHP
php 数组排序 array_multisort与uasort的区别
Mar 24 PHP
PHP学习之整理字符串
Apr 17 PHP
用php来改写404错误页让你的页面更友好
Jan 24 PHP
php基于表单密码验证与HTTP验证用法实例
Jan 06 PHP
PHP共享内存用法实例分析
Feb 12 PHP
php的闭包(Closure)匿名函数初探
Feb 14 PHP
PHP使用星号替代用户名手机和邮箱的实现代码
Feb 07 PHP
PHP简单实现防止SQL注入的方法
Mar 13 PHP
PHP实现动态添加XML中数据的方法
Mar 30 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
MySQL中create table语句的基本语法是
2007/01/15 PHP
php中判断文件空目录是否有读写权限的函数代码
2012/08/07 PHP
php采用curl访问域名返回405 method not allowed提示的解决方法
2014/06/26 PHP
php实现网站顶踩功能的完整前端代码
2015/07/19 PHP
学习php设计模式 php实现适配器模式
2015/12/07 PHP
Laravel6.0.4中将添加计划任务事件的方法步骤
2019/10/15 PHP
在thinkphp5.0路径中实现去除index.php的方式
2019/10/16 PHP
jQuery(js)获取文字宽度(显示长度)示例代码
2013/12/31 Javascript
jQuery获取节点和子节点文本的方法
2014/07/22 Javascript
IE6/IE7中JavaScript json提示缺少标识符、字符串或数字问题处理
2014/12/16 Javascript
jQuery实现的超酷苹果风格图标滑出菜单效果代码
2015/09/16 Javascript
AngularJs学习第八篇 过滤器filter创建
2016/06/08 Javascript
浅谈Vuejs中nextTick()异步更新队列源码解析
2017/12/31 Javascript
从零开始搭建webpack+react开发环境的详细步骤
2018/05/18 Javascript
讲解vue-router之什么是编程式路由
2018/05/28 Javascript
利用d3.js力导布局绘制资源拓扑图实例教程
2019/01/08 Javascript
微信小程序基于canvas渐变实现的彩虹效果示例
2019/05/03 Javascript
vue 微信分享回调iOS和安卓回调出现错误的解决
2020/09/07 Javascript
[40:31]Secret vs Alliacne 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
二种python发送邮件实例讲解(python发邮件附件可以使用email模块实现)
2013/12/03 Python
Python实现读取目录所有文件的文件名并保存到txt文件代码
2014/11/22 Python
在win64上使用bypy进行百度网盘文件上传功能
2020/01/02 Python
Pytorch中实现只导入部分模型参数的方式
2020/01/02 Python
Python drop方法删除列之inplace参数实例
2020/06/27 Python
keras和tensorflow使用fit_generator 批次训练操作
2020/07/03 Python
python如何调用java类
2020/07/05 Python
html5教程画矩形代码分享
2013/12/04 HTML / CSS
JOSEPH官网:英国奢侈时尚品牌
2018/01/31 全球购物
介绍一下RMI的基本概念
2016/12/17 面试题
写给老师的表扬信
2014/01/21 职场文书
新学期教师寄语
2014/04/02 职场文书
毕业生政审意见范文
2015/06/04 职场文书
公司会议开幕词
2016/03/03 职场文书
SQL实现LeetCode(178.分数排行)
2021/08/04 MySQL
如何解决php-fpm启动不了问题
2021/11/17 PHP
Python制作春联的示例代码
2022/01/22 Python