PHP命名空间下的自动加载

PHP 2016-08-05

前言

命名空间的出现解决了类/函数/常量之间的名字冲突。使得在新建一个对象的时候需要指定其所在空间:

$req = new Framework\App\Request();

由于空间的出现,以前自动加载的函数似乎就不那么好用了:

function __autoload($className) {
    static $map = array();
    if (!isset($map[$className])) {
        require __APP__.'classes/'.$className.'.php';
        $map[$className] = true;
    }
}

命名空间的用法

定义

命名空间通过namespace定义,它将影响到类,接口,函数和常量.

<?php
namespace Controller;
class IndexController{}

如果要定义一个文件的命名空间,则声明写在所有代码之前。如果没指定命名空间,则它属于空间,是全局属性的。

子空间

将空间层次化,定义形如:namespace Blog\Model\User;

php是动态的脚本语言,所以不像java那样需要靠目录与文件对应关系定义包名,也就是说在php中空间的名称与目录无关。然而为了开发规范以及后续自动载入函数的使用,空间命名规格与目录对应是很有帮助的。

一个文件的多空间下建议用大括号{}包裹.

使用

<?php
namespace App;
include 'a.php';//必须包含A命名空间的文件 namespace A;
include 'b.php';//namespace B;

$a = new A\User();//报错,因为当前空间App,会被解析为App\A\User
$a = new \A\User();
$a->fun();

使用中可以通过 __NAMESPACE__ 来查看当前命名空间。

省力的use

<?php
namespace App;
use A\User; //导入A空间下的User类 可以导到具体类,可以导到命名空间
use B\User as Name; //as取命名
include 'a.php';
include 'b.php';

$a = new User();
$a->fun();
$b = new Name();
$b->fun();

注意:加了命名空间后,常量__CLASS__的值为空间名\类名;而通过use as 重新取别名后不变其值。

更多内容可以查看:PHP: 使用命名空间:基础

自动加载

Tip spl_autoload_register() 提供了一种更加灵活的方式来实现类的自动加载。因此,不再建议使用 __autoload() 函数,在以后的版本中它可能被弃用。

原型为:bool spl_autoload_register ([ callable $autoload_function [, bool $throw = true [, bool $prepend = false ]]] ) 并且这个函数可定义多次,相当于注册了__autoload()队列。

<?php
namespace App;

function autoload($class) {
    static  $map = array();
    //定义搜索目录
    $dirs = array(
        __DIR__,
        __DIR__.'/Lib/',
        __DIR__.'/classes/',
    );

    if(!isset($map[$class])) {
        foreach ($dirs as $dir) {
            $file = $dir.'/'.str_replace('\\', '/', $class). '.class.php';
            if (file_exists($file)) {
                require $file;
                $map[$class] = true;
            }
        }
    }
}

//注册
spl_autoload_register('App\autoload');

//使用
$a = new \Blog\User();/文件命名为User.class.php
$a->fun();

更多内容可以查看:PHP: 自动加载类


本文由 hongweipeng 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

赏个馒头吧