PHP命名空间与自动加载机制的基础介绍

前言

include 和 require 是PHP中引入文件的两个基本方法。在小规模开发中直接使用 include 和 require 没哟什么不妥,但在大型项目中会造成大量的 include 和 require 堆积。这样的代码既不优雅,执行效率也很低,而且维护起来也相当困难。

为了解决这个问题,部分框架会给出一个引入文件的配置清单,在对象初始化的时候把需要的文件引入。但这只是让代码变得更简洁了一些,引入的效果仍然是差强人意。PHP5 之后,随着 PHP 面向对象支持的完善,__autoload 函数才真正使得自动加载成为可能。

* include 和 require 功能是一样的,它们的不同在于 include 出错时只会产生警告,而 require 会抛出错误终止脚本。

* include_once 和 include 唯一的区别在于 include_once 会检查文件是否已经引入,如果是则不会重复引入。

=================自动加载==================

实现自动加载最简单的方式就是使用 __autoload 魔术方法。当需要使用的类没有被引入时,这个函数会在PHP报错前被触发,未定义的类名会被当作参数传入。至于函数具体的逻辑,这需要用户自己去实现。

首先创建一个 autoload.php 来做一个简单的测试:

// 类未定义时,系统自动调用
function __autoload($class)
{
 /* 具体处理逻辑 */
 echo $class;// 简单的输出未定义的类名
}

new HelloWorld();

/**
 * 输出 HelloWorld 与报错信息
 * Fatal error: Class 'HelloWorld' not found
 */

通过这个简单的例子可以发现,在类的实例化过程中,系统所做的工作大致是这样的:

/* 模拟系统实例化过程 */
function instance($class)
{
 // 如果类存在则返回其实例
 if (class_exists($class, false)) {
  return new $class();
 }
 // 查看 autoload 函数是否被用户定义
 if (function_exists('__autoload')) {
  __autoload($class); // 最后一次引入的机会
 }
 // 再次检查类是否存在
 if (class_exists($class, false)) {
  return new $class();
 } else { // 系统:我实在没辙了
  throw new Exception('Class Not Found');
 }
}

明白了 __autoload 函数的工作原理之后,那就让我们来用它去实现自动加载。

首先创建一个类文件(建议文件名与类名一致),代码如下:

class [ClassName] 
{
 // 对象实例化时输出当前类名
 function __construct()
 {
  echo '<h1>' . __CLASS__ . '</h1>';
 }
}

(我这里创建了一个 HelloWorld 类用作演示)接下来我们就要定义 __autoload 的具体逻辑,使它能够实现自动加载:

function __autoload($class)
{
 // 根据类名确定文件名
 $file = $class . '.php';

 if (file_exists($file)) {
  include $file; // 引入PHP文件
 }
}

new HelloWorld();

/**
 * 输出 <h1>HelloWorld</h1>
 */
      

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/5306.html