详解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 相关文章推荐
PHP 中的面向对象编程:通向大型 PHP 工程的办法
Dec 03 PHP
用php实现的获取网页中的图片并保存到本地的代码
Jan 05 PHP
解析thinkphp import 文件内容变量失效的问题
Jun 20 PHP
图解找出PHP配置文件php.ini的路径的方法
Aug 20 PHP
php返回json数据函数实例
Oct 09 PHP
PHP封装分页函数实现文本分页和数字分页
Oct 23 PHP
php防止恶意刷新与刷票的方法
Nov 21 PHP
PHP 常用的header头部定义汇总
Jun 19 PHP
在Laravel中使用DataTables插件的方法
May 29 PHP
java解析json方法总结
May 16 PHP
php使用filter_var函数判断邮箱,url,ip格式示例
Jul 06 PHP
关于Yii中模型场景的一些简单介绍
Sep 22 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 chr() ord()中文截取乱码问题解决方法
2008/09/08 PHP
PHP 处理图片的类实现代码
2009/10/23 PHP
php 常用类汇总 推荐收藏
2010/05/13 PHP
Apache中php.ini的设置方法
2013/02/28 PHP
PHP IE中下载附件问题解决方法
2014/01/07 PHP
PHP中功能强大却很少使用的函数实例小结
2016/11/10 PHP
Laravel5.5以下版本中如何自定义日志行为详解
2018/08/01 PHP
php 中htmlentities导致中文无法查询问题
2018/09/10 PHP
JS的IE和Firefox兼容性集锦
2006/12/11 Javascript
一份老外写的XMLHttpRequest代码多浏览器支持兼容性
2007/01/11 Javascript
非主流的textarea自增长实现js代码
2011/12/20 Javascript
基于jquery的网站幻灯片切换效果焦点图代码
2013/09/15 Javascript
javascript模拟post提交隐藏地址栏的参数
2014/09/03 Javascript
在AngularJS中使用AJAX的方法
2015/06/17 Javascript
js下将金额数字每三位一逗号分隔
2016/02/19 Javascript
JavaScript入门教程之引用类型
2016/05/04 Javascript
js弹出窗口返回值的简单实例
2016/05/28 Javascript
Vue声明式渲染详解
2017/05/17 Javascript
js HTML5 canvas绘制图片的方法
2017/09/08 Javascript
jQuery实现的页面遮罩层功能示例【测试可用】
2017/10/14 jQuery
浅谈Vue路由快照实现思路及其问题
2018/06/07 Javascript
nodejs搭建本地服务器并访问文件操作示例
2019/05/11 NodeJs
JS中的算法与数据结构之集合(Set)实例详解
2019/08/20 Javascript
jQuery实时统计输入框字数及限制
2020/06/24 jQuery
在vue-cli3.0 中使用预处理器 (Sass/Less/Stylus) 配置全局变量操作
2020/08/10 Javascript
Python的Flask框架中使用Flask-SQLAlchemy管理数据库的教程
2016/06/14 Python
Python 使用元类type创建类对象常见应用详解
2019/10/17 Python
简单了解django文件下载方式
2020/02/10 Python
从python读取sql的实例方法
2020/07/21 Python
python 将Excel转Word的示例
2021/03/02 Python
css3实例教程 一款纯css3实现的发光屏幕旋转特效
2014/12/07 HTML / CSS
馥绿德雅美国官方网站:Rene Furterer头皮护理专家
2019/05/01 全球购物
Linux面试题LINUX系统类
2015/11/25 面试题
中学团支部工作总结
2015/08/13 职场文书
给原生html中添加水印遮罩层的实现示例
2021/04/02 Javascript
angular4实现带搜索的下拉框
2022/03/25 Javascript