之前一直没有注意到一个细节,今天在写程序时候,无意中遇到一个问题,才发现原来php中命名空间与java中包的概念差别还是非常大的。php自5.3.0开始引入命名空间的概念,和java类似,都是封装思想的一种体现,力求解决不同文件或是相同文件中类、函数、变量、常量名字冲突的问题。可是经过测试发现,php的命名空间貌似只是解决了类、函数名字冲突问题,并没有解决php中变量、或是常量冲突问题。
首先,还是简单了解一下命名空间,定义命名空间使用namespace,引用命名空间使用use。如果在定义一个函数或是定义一个类的时候,不添加命名空间,默认的在根命名空间,根命名空间使用'\'表示,在实例化对象的时候,如果不添加命名空间,代表实力化当前命名空间中的类。
class Student{
public static function showName(){
echo 'my name is dequan from Local </br>';
}
}
function test($params){
echo $params.',hello</br>';
}
$s1=new Student();//实例化当前命名空间中的类,当前命名空间为根命名空间
$s1->showName();
test('s1'); //调用当前命名空间中的函数
$s2=new \Student(); //实例化根命名空间中的类
$s2->showName();//调用根命名空间中的函数
\test('s2');
下面通过两个例子来展示命名空间解决同名类和同名函数的问题
文件index1.php
namespace henan\school;
class Student{
public static function showName(){
echo 'my name is dequan from henan </br>';
}
}<pre name="code" class="php" style="text-indent: 30px;">function test(){
<span> </span>echo 'henan hubei</br>';
}
namespace hubei\school;class Student{public static function showName(){echo 'my name is dequan from hubei </br>';}} function test(){echo 'henan hubei</br>';
}
文件index.php
include "index1.php";
$s1=new \henan\school\Student();//也可以使用$s1=new henan\school\Student();,因为当前命名空间是根空间,所以可以省略\,为了代码严谨性,推荐加上\
$s1->showName();
\henan\school\test();
$s2=new \hubei\school\Student();
$s2->showName();
\hubei\school\test();
当命名空间遇到同名变量和同名常量时候,确束手无策了
文件index1.php
namespace henan\school;
$params='I am from henan';
namespace hubei\school;
$params='I am from hubei';
文件index.phpinclude "index1.php";
echo $params; //I am from hubei
echo '</br>';
use \henan\school as curSchool1;
echo $params; //I am from hubei
echo '</br>';
use \hubei\school as curSchool2;
echo $params; //I am from hubei
echo '</br>';
这说明一个道理,在php的各个命名空间中的变量是相互通用的,就相当于定义在根命名空间下,或者说php中的变量,没有命名空间之分。常量也是这样的,看下面脚本namespace henan\school;
define('FROMWHERE', 'HeNan');
namespace hubei\school;
define('FROMWHERE', 'HuBei');//将会报错,提示FROMWHERE已经定义
备注:笔者当前使用php版本为5.5.12