详解PHP文件的自动加载(autoloading)


Posted in PHP onFebruary 04, 2018

传统上,在PHP里,当我们要用到一个class文件的时候,我们都得在文档头部require或者include一下:

<?php
require_once('../includes/functions.php');
require_once('../includes/database.php');
require_once('../includes/user.php');
...

但是一旦要调用的文档多了,就得每次都写一行,瞅着也不美观,有什么办法能让PHP文档自动加载呢?

<?php
function __autoload($class_name)
{
  require "./{$class_name}.php";
}

对,可以使用PHP的魔法函数__autoload(),上面的示例就是自动加载当前目录下的PHP文件。当然,实际当中,我们更可能会这么来使用:

<?php
function __autoload($class_name)
{
  $name = strtolower($class_name);
  $path = "../includes/{$name}.php";
  
  if(file_exists($path)){
     require_once($path);
    }else{
      die("the file {$class_name} could not be found");
    }
}

也即是做了一定的文件名大小写处理,然后在require之前检查文件是否存在,不存在的话显示自定义的信息。

类似用法经常在私人项目,或者说是单一项目的框架中见到,为什么呢?因为你只能定义一个__autoload function,在多人开发中,做不到不同的developer使用不同的自定义的autoloader,除非大家都提前说好了,都使用一个__autoload,涉及到改动了就进行版本同步,这很麻烦。

也主要是因为此,有个好消息,就是这个__autoload函数马上要在7.2版本的PHP中弃用了。

Warning This feature has been DEPRECATED as of PHP 7.2.0. Relying on this feature is highly discouraged.
那么取而代之的是一个叫spl_autoload_register()的东东,它的好处是可以自定义多个autoloader.

//使用匿名函数来autoload
spl_autoload_register(function($class_name){
  require_once('...');
});
//使用一个全局函数
function Custom()
{
  require_once('...');
}

spl_autoload_register('Custom');
//使用一个class当中的static方法
class MyCustomAutoloader
{
  static public function myLoader($class_name)
  {
    require_once('...');    
  }
}

//传array进来,第一个是class名,第二个是方法名
spl_autoload_register(['MyCustomAutoloader','myLoader']);
//甚至也可以用在实例化的object上
class MyCustomAutoloader
{
  public function myLoader($class_name)
  {
  }
}

$object = new MyCustomAutoloader;
spl_autoload_register([$object,'myLoader']);

值得一提的是,使用autoload,无论是__autoload(),还是spl_autoload_register(),相比于require或include,好处就是autoload机制是lazy loading,也即是并不是你一运行就给你调用所有的那些文件,而是只有你用到了哪个,比如说new了哪个文件以后,才会通过autoload机制去加载相应文件。

当然,laravel包括各个package里也是经常用到spl_autoload_register,比如这里:

/**
 * Prepend the load method to the auto-loader stack.
 *
 * @return void
 */
protected function prependToLoaderStack()
{
  spl_autoload_register([$this, 'load'], true, true);
}
PHP 相关文章推荐
如何将数据从文本导入到mysql
Oct 09 PHP
Discuz! 5.0.0论坛程序中加入一段js代码,让会员点击下载附件前自动弹出提示窗口
Apr 18 PHP
全局记录程序片段的运行时间 正确找到程序逻辑耗时多的断点
Jan 06 PHP
php file_put_contents()功能函数(集成了fopen、fwrite、fclose)
May 24 PHP
php和数据库结合的一个简单的web实例 代码分析 (php初学者)
Jul 28 PHP
PHP文章采集URL补全函数(FormatUrl)
Aug 02 PHP
php使HTML标签自动补全闭合函数代码
Oct 04 PHP
浅析php中三个等号(===)和两个等号(==)的区别
Aug 06 PHP
Laravel框架数据库CURD操作、连贯操作总结
Sep 03 PHP
php针对cookie操作的队列操作类实例
Dec 10 PHP
Yii2中如何使用modal弹窗(基本使用)
May 30 PHP
PHP生成二维码与识别二维码的方法详解【附源码下载】
Mar 07 PHP
PHP实现QQ登录的开原理和实现过程
Feb 04 #PHP
PHP实现正则表达式分组捕获操作示例
Feb 03 #PHP
php实现解析xml并生成sql语句的方法
Feb 03 #PHP
PHP删除数组中指定下标的元素方法
Feb 03 #PHP
php学习笔记之mb_strstr的基本使用
Feb 03 #PHP
php通过pecl方式安装扩展的实例讲解
Feb 02 #PHP
PHP实现对图片的反色处理功能【测试可用】
Feb 01 #PHP
You might like
在PHP中利用wsdl创建标准webservice的实现代码
2011/12/07 PHP
php生成静态页面的简单示例
2014/04/17 PHP
php设计模式之单例模式实例分析
2015/02/25 PHP
php+ajax简单实现全选删除的方法
2016/12/06 PHP
Yii2框架可逆加密简单实现方法
2017/08/25 PHP
Google AJAX 搜索 API实现代码
2010/11/17 Javascript
js 分页全选或反选标识实现代码
2011/08/09 Javascript
阻止事件(取消浏览器对事件的默认行为并阻止其传播)
2013/11/03 Javascript
使用apply方法实现javascript中的对象继承
2013/12/16 Javascript
jquery使用$(element).is()来判断获取的tagName
2014/08/24 Javascript
node.js中的fs.createWriteStream方法使用说明
2014/12/17 Javascript
jQuery+css实现的tab切换标签(兼容各浏览器)
2016/01/28 Javascript
jQuery隐藏和显示效果实现
2016/04/06 Javascript
基于jquery实现图片放大功能
2016/05/07 Javascript
移动端 一个简单易懂的弹出框
2016/07/06 Javascript
微信公众平台开发教程(六)获取个性二维码的实例
2016/12/02 Javascript
使用mint-ui开发项目的一些心得(分享)
2017/09/07 Javascript
vue获取当前点击的元素并传值的实例
2018/03/09 Javascript
Bootstrap实现前端登录页面带验证码功能完整示例
2020/03/26 Javascript
[02:05]2014DOTA2国际邀请赛 BBC外卡赛赛后总结
2014/07/09 DOTA
python daemon守护进程实现
2016/08/27 Python
python微信好友数据分析详解
2018/11/19 Python
pandas读取csv文件,分隔符参数sep的实例
2018/12/12 Python
python 中不同包 类 方法 之间的调用详解
2020/03/09 Python
python opencv实现图片缺陷检测(讲解直方图以及相关系数对比法)
2020/04/07 Python
Python flask框架实现浏览器点击自定义跳转页面
2020/06/04 Python
css3中用animation的steps属性制作帧动画
2019/04/25 HTML / CSS
英国打印机墨水和碳粉商店:Printerinks
2017/06/30 全球购物
重新定义牛仔布,100美元以下:Warp + Weft
2018/07/25 全球购物
3D空间设计学生找工作的自我评价
2013/10/28 职场文书
酒店中秋节活动方案
2014/01/31 职场文书
人民调解员先进事迹材料
2014/05/08 职场文书
就职演讲稿范文
2014/05/19 职场文书
教你怎么用Python操作MySql数据库
2021/05/31 Python
基于Java的MathML转图片的方法(示例代码)
2021/06/23 Java/Android
FFmpeg视频处理入门教程(新手必看)
2022/01/22 杂记