PHP命名空间与自动加载简述

图片来自www.ngchina.com.cn网

命名空间(PHP 5 >= 5.3.0, PHP 7)

什么是命名空间?从广义上来讲,命名空间是一种封装事物的方法。在不少地方均可以见到这种抽象概念。例如,在操做系统中目录用来将相关文件分组,对于目录中的文件来讲,它就扮演了命名空间的角色。具体举个例子,文件 foo.txt 能够同时在目录/home/greg 和 /home/other 中存在,但在同一个目录中不能存在两个 foo.txt 文件。另外,在目录 /home/greg 外访问 foo.txt 文件时,咱们必须将目录名以及目录分隔符放在文件名以前获得 /home/greg/foo.txt。这个原理应用到程序设计领域就是命名空间的概念。php

在PHP中,命名空间用来解决在编写类库或应用程序时建立可重用的代码如类或函数时碰到的两类问题:composer

  1. 用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
  2. 为很长的标识符名称(一般是为了缓解第一类问题而定义的)建立一个别名(或简短)的名称,提升源代码的可读性。

PHP 命名空间提供了一种将相关的类、函数和常量组合到一块儿的途径。函数

举栗子:ui

file.php 文件
<?php
// 使用namespace关键字定义命名空间,
// 且以前不能有东西
namespace Test;  
const IN = 'oooo';
function tete() {
    return __METHOD__;
}
class lala {
    function init() {
        return __METHOD__;
    }
}
autoload.php 文件
<?php
include 'file.php';
// 函数和常量是不支持use导入规则的,只有类能支持导入规则。
// 若是只是使用use Test就会报错 The use statement with non-compound name 'Test' has no effect in..
use Test\lala;   // 也能够use Test\lala as lululu;
echo Test\IN."\n";
$te = new lala(); // new lululu(); // 也可使用这样的方式来避免两个相同的类名称
复制代码

总结:spa

  • 虽然任意合法的PHP代码均可以包含在命名空间中,但只有如下类型的代码受命名空间的影响,它们是:类(包括抽象类和traits)、接口、函数和常量。
  • 命名空间经过关键字namespace 来声明。若是一个文件中包含命名空间,它必须在其它全部代码以前声明命名空间,除了一个之外:declare关键字。
  • 与目录和文件的关系很象,PHP 命名空间也容许指定层次化的命名空间的名称。如「namespace MyProject\Sub\Level;」
  • 也能够在同一个文件中定义多个命名空间,可是要使用大括号的形式。例如:
namespace MyProject {
    const CONNECT_OK = 1;
    class Connection { /* ... */ }
    function connect() { /* ... */  }
}

namespace AnotherProject {
    const CONNECT_OK = 1;
    class Connection { /* ... */ }
    function connect() { /* ... */  }
}
复制代码

以上这些是简单的概述,详情请移步php官网操作系统

自动加载

在编写面向对象(OOP) 程序时,不少开发者为每一个类新建一个 PHP 文件。 这会带来一个烦恼:每一个脚本的开头,都须要包含(include)一个长长的列表(每一个类都有个文件)。例如:.net

<?php

include "test1.php";
include "test2.php";
include "test3.php";
......
复制代码

那如何避免这种状况呢? 在 PHP 5 中,已经再也不须要这样了。 spl_autoload_register() 函数能够注册任意数量的自动加载器,当使用还没有被定义的类(class)和接口(interface)时自动去加载。经过注册自动加载器,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类。举一个栗子:设计

lala.php 文件
<?php
class lala {
    function init() {
        return __METHOD__;
    }
}

autoload.php 文件
<?php
spl_autoload_register(function ($class_name){
    // 在这里引入将要加载的类文件
    // 可是有一点,加载的类文件的文件名称必须是和类名称同样
    require_once $class_name.'.php'; 
});
$tt = new lala();
$tt->init();
复制代码

如今随便一个很小的项目都须要几十个甚至几百个类,固然了不一样功能的类还须要区分在不一样的文件夹中,这样加载就有点麻烦了。 在这里咱们引入PSR-4自动加载规范。结合上面咱们所讲到的命名空间,在规范内就能够轻松解决咱们心里的担心。code

.目录结构
├── App
│   └── MyClass.php
└── test.php
MyClass.php文件
<?php 
namespace App;
class MyClass {
	public function WhoAmI() {
		return __METHOD__;
	}
}

test.php文件
<?php
spl_autoload_register(function($class_name) {
	require_once str_replace('\\','/',$class_name).'.php';
});
use App\MyClass as MC;
$obj = new MC();
echo $obj->WhoAmI()."\n";  // App\MyClass::WhoAmI
复制代码

这只是一个简单的例子,想要了解实际项目中的自动加载的概念,能够移步composer。固然了首先要知道PSR-4的相关规范......cdn

时2018年4月24日写

相关文章
相关标签/搜索