详解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 相关文章推荐
简单采集了yahoo的一些数据
Feb 14 PHP
PHP如何编写易读的代码
Jul 10 PHP
PHP中文分词 自动获取关键词介绍
Nov 13 PHP
php设置允许大文件上传示例代码
Mar 10 PHP
Laravel 5框架学习之环境与配置
Apr 08 PHP
ThinkPHP文件缓存类代码分享
Apr 22 PHP
PHP安装memcached扩展笔记
May 28 PHP
ThinkPHP中limit()使用方法详解
Apr 19 PHP
Joomla实现组件中弹出一个模式(modal)窗口的方法
May 04 PHP
Yii2框架数据库简单的增删改查语法小结
Aug 31 PHP
php file_get_contents取文件中数组元素的方法
Apr 01 PHP
基于PHP的微信公众号的开发流程详解
Aug 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
桌面中心(二)数据库写入
2006/10/09 PHP
php5.2.0内存管理改进
2007/01/22 PHP
thinkphp3.2中实现phpexcel导出带生成图片示例
2017/02/14 PHP
PHP实现的redis主从数据库状态检测功能示例
2017/07/20 PHP
Laravel中服务提供者和门面模式的入门介绍
2017/11/06 PHP
一个对于Array的简单扩展
2006/10/03 Javascript
JS面向对象编程 for Cookie
2010/09/19 Javascript
js给onclick事件赋值,动态传参数实例解说
2013/03/28 Javascript
JavaScript sup方法入门实例(把字符串显示为上标)
2014/10/20 Javascript
nodejs简单实现中英文翻译
2015/05/04 NodeJs
vue 通过下拉框组件学习vue中的父子通讯
2017/12/19 Javascript
vue element-ui 绑定@keyup事件无效的解决方法
2018/03/09 Javascript
vue-devtools的安装步骤
2018/04/23 Javascript
vue-router传递参数的几种方式实例详解
2018/11/13 Javascript
详解ES6系列之私有变量的实现
2018/11/21 Javascript
Vue 使用formData方式向后台发送数据的实现
2019/04/14 Javascript
运用js实现图层拖拽的功能
2019/05/24 Javascript
详解vue中v-bind:style效果的自定义指令
2020/01/21 Javascript
在vue中配置不同的代理同时访问不同的后台操作
2020/09/11 Javascript
Python ftp上传文件
2016/02/13 Python
PyQt5打开文件对话框QFileDialog实例代码
2018/02/07 Python
pycharm 将python文件打包为exe格式的方法
2019/01/16 Python
pycharm中leetcode插件使用图文详解
2020/12/07 Python
美国男女折扣服饰百货连锁店:Stein Mart
2017/05/02 全球购物
瑞士网球商店:Tennis-Point
2020/03/12 全球购物
酒店个人培训自我鉴定
2013/12/11 职场文书
司仪主持词两篇
2014/03/22 职场文书
买卖车协议书
2014/04/21 职场文书
集中采购方案
2014/06/10 职场文书
异地年检委托书范本
2014/09/24 职场文书
北大自主招生自荐信
2015/03/04 职场文书
初中生活随笔
2015/08/15 职场文书
传单、海报早OUT了,另类传单营销方案送给你!
2019/07/15 职场文书
php中pcntl_fork详解
2021/04/01 PHP
Java 超详细讲解设计模式之中的抽象工厂模式
2022/03/25 Java/Android
Java8 Stream API 提供了一种高效且易于使用的处理数据的方式
2022/04/13 Java/Android