面向对象之命名空间

操作系统中文件名冲突

操作系统中用目录来将相关文件分组,这个设计思想就是我们命名空间的概念:

一、什么是命名空间

命名空间就是文件夹,在不同的命令空间下面就可以有相同的类名

在开发中(PHP5.3+),使用命名空间解决两类问题:

  1. 用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。

  2. 为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性
## 寻秦记 QinGuo 秦国  HongKong香港
namespace QinGuo;
header('content-type:text/html;charset=utf-8');

class XiangShaoLong 
{
    public $name = '项少龙';

    public function say(){
        echo 'I 服 了 you 赵王';
    }
}

namespace HongKong;
class XiangShaoLong 
{
    public $name = '项少龙';

    public function say(){
        echo 'I 服 了 you 香港';
    }
}

$person = new XiangShaoLong();
$person->say();

需要注意 1、在实际的编程实践中,非常不提倡在同一个文件中定义多个命名空间

2、第一个命名空间 前面不能有任何代码,必须是程序脚本的第一条语句。否则报错

<html>
<?php
namespace my;//这样会报错

3、在命名空间里,define的作用是全局的,而const则作用于当前空间

namespace QinGuo;
define('NAME','xxx');
const AGE = 18;

namespace HongKong;
echo NAME;
echo AGE;

根空间(公共空间)

一个脚本里没有定义其它命名空间,它的元素就始终处于根空间(公共空间)中:\

工具类:tools.class.php

<?php
class Tools
{
    public static function getIp()
    {
        return 1111;
    }
}

使用工具类

namespace Myobject;

include('tools.class.php');
const JACK = 'nie';

//echo Tools::getIp();//Fatal error: Class 'Myobject\Tools' not found
echo \Tools::getIp();

调用根空间的方式是直接在元素名称前加 '\' 就可以了,否则PHP解析器会认为我想调用当前空间下的元素。除了自定义的元素,还包括PHP自带的元素,都属于根空间。

二、子空间

路径很像 子空间还可以定义很多层次,

namespace MySpace\myobject;

class demo
{
    public $name = 'my';
}

namespace YouSpace;
class demo
{
    public $name = 'you';
}

$c = new demo();
echo $c->name;
echo '<hr/>';

$a = new \MySpace\myobject\demo();
echo $a->name;

四、类名通过三种方式引用

1、 非限定名称,或不包含前缀的类名称。 默认没有使用命名空间调用的元素,命名空间就是当前。

namespace HongKong\jiulong;
function foo(){
}

class foo
{
    static function myMethod() {}
}

foo(); //命名空间:HongKong\jiulong\foo
foo::myMethod(); //命名空间:HongKong\jiulong\foo类中静态方法

2、 限定名称,或包含前缀的名称,

namespace test;
function foo(){
}

class foo
{
    static function myMethod() {}
}

namespace HongKong\jiulong;

test\foo(); //命名空间:HongKong\jiulong\test\foo
test\foo::myMethod(); //命名空间:HongKong\jiulong\test\foo类中静态方法

3、完全限定名称,或包含了全局前缀操作符的名称

namespace HongKong\jiulong;
function foo(){
}

class foo
{
    static function myMethod() {}
}

\HongKong\jiulong\foo(); //命名空间:\HongKong\jiulong\foo()
\HongKong\jiulong\foo::myMethod(); //命名空间:\HongKong\jiulong\foo类中静态方法

五、引用和别名

它们都是通过使用 use 操作符来实现,使用别名 as 为很长的标识符名称创建一个别名的名称,提高源代码的可读性。

namespace Blog\Article;
class Comment
{
    public $name = 'jack';
}

namespace BBS;
//use Blog\Article; //引入
use Blog\Article as Art; //别名

$c = new Art\Comment();
echo $c->name;

六、利用namespace和__NAMESPACE__动态调用

namespace MyObject;
class demo
{
    public $name;
}

echo __NAMESPACE__;
$c = new namespace\demo();
class test()
{
    function  get ( $classname )
    {
        $a  =  __NAMESPACE__ .'\\'.$classname ;
        return new  $a ;
    }
}