php里面的namespace

namespace以前学C++的时候有接触过,在OC里面因为没有命名空间一直被大家诟病,只能用前缀如AFNS之类的区分开来,而php从5.3之后也加入了namespace。

namespace的引入就是为了解决类名重复、方法名重复的问题。毕竟你自己写代码还能注意不重名,但composer引入第三方库就未必了。所以namespace的重要作用就体现出来了。

namespace如何避免类名重复

假如说,有两个文件a.php,b.php,内容分别如下:

a.php的内容

<?php
class Helper {
	public function test() {
          echo '-lib1--class Helper function test--'."\n";
 
      }
}
?>

b.php的内容

<?php
class Helper {
	public function test() {
          echo '-lib2--class Helper function test--'."\n";
 
      }
}
?>

我要调用这两个文件里面的方法,代码如下

index.php的内容

<?php
	require __DIR__.'/a.php';
	require __DIR__.'/b.php';

	$h1 = new Helper();
	$h1->test();

	$h2 = new Helper();
	$h2->test();
?>

这样会报错,Cannot redeclare class Helper,因为有两个类,都叫Helper


给他们加上命名空间,再来看结果

**注意:**声明命名空间的时候,namespace之前不能有任何代码。

a.php的内容

<?php

namespace A;
class Helper {
	public function test() {
          echo '-lib1--class Helper function test--'."\n";
 
      }
}
?>

b.php的内容

<?php

namespace B;
class Helper {
	public function test() {
          echo '-lib2--class Helper function test--'."\n";
 
      }
}
?>

index.php的内容

<?php
	require __DIR__.'/a.php';
	require __DIR__.'/b.php';

	$h1 = new A\Helper();
	$h1->test();

	$h2 = new B\Helper();
	$h2->test();
?>

可以正确输出:

-lib1--class Helper function test--
-lib2--class Helper function test--

上面是在类名前直接加上了namespace的名字,当然也可以使用use关键字来申明使用的命名空间

index.php的内容

<?php

require __DIR__.'/a.php';
require __DIR__.'/b.php';

use A\Helper;
$h1 = new Helper();
$h1->test();

use B\Helper as H;
$h2 = new H();
$h2->test();
?>

也可以正确输出

-lib1--class Helper function test--
-lib2--class Helper function test--

需要注意的是,上方使用use A\Helper;指明了一个命名空间里面的Helper类,下面不能也用use B\Helper;,它会报错Cannot use B\Helper as Helper because the name is already in use。需要使用as关键字来改名字,例如上方use B\Helper as H;就把命名空间B里面的Helper类赋予了一个别名叫H


上面说的是如何使用namespace来避免类名重复,下面说如何使用命名空间来避免function名字重复

比如说我有两个文件fun1.php和fun2.php,内容如下:

fun1.php的内容:

<?php

function test() {
    echo '--in fun1.php test()--' . "\n";
}
?>

fun2.php的内容:

<?php

function test() {
    echo '--in fun2.php test()--' . "\n";
}
?>

index.php的内容

<?php

require __DIR__.'/fun1.php';
require __DIR__.'/fun2.php';

test();
?>

运行index.php文件,会报错Cannot redeclare test(),因为有两个同名的function。下面使用namespace来区分他们。

fun1.php的内容:

<?php

namespace A;
function test() {
    echo '--in fun1.php test()--' . "\n";
}
?>

fun2.php的内容:

<?php

namespace B;
function test() {
    echo '--in fun2.php test()--' . "\n";
}
?>

index.php的内容

<?php

require __DIR__.'/fun1.php';
require __DIR__.'/fun2.php';

function test() {
    echo '--in index.php test()--' . "\n";
}

A\test();
B\test();

test();
?>

那么可以正确输出如下:

--in fun1.php test()--
--in fun2.php test()--
--in index.php test()--

如果使用use关键字,应该如何使用呢?

index.php的内容

<?php

require __DIR__.'/fun1.php';
require __DIR__.'/fun2.php';

function test() {
    echo '--in index.php test()--' . "\n";
}

use A;
test();

use B;
test();

test();
?>

抛出了两个warning,The use statement with non-compound name 'A' has no effectThe use statement with non-compound name 'B' has no effect,并且打印结果是:

--in index.php test()--
--in index.php test()--
--in index.php test()--

使用as关键字进行别名,修改index.php的内容

index.php的内容

<?php

require __DIR__.'/fun1.php';
require __DIR__.'/fun2.php';

function test() {
    echo '--in index.php test()--' . "\n";
}

use A as a;
a\test();

use B as b;
b\test();

test();
?>

终于能够正常打印了

--in fun1.php test()--
--in fun2.php test()--
--in index.php test()--