PHP——命名空间(namespace)使用详细介绍-php教程

资源魔 46 0
关于定名空间,民间文档曾经说患上很具体[查看],我正在这里做了一下理论以及总结。

定名空间一个最明白的目的就是处理重名成绩,PHP中没有容许两个函数或许类呈现相反的名字,不然会孕育发生一个致命的谬误。这类状况下只需防止定名反复就能够处理,最多见的一种做法是商定一个前缀。

例:名目中有两个模块:article以及message board,它们各自有一个解决用户留言的类Co妹妹ent。之后我可能想要添加对一切用户留言的一些信息统计性能,比方说我想失去一切留言的数目。这时候候挪用它们Co妹妹ent提供的办法是很好的做法,然而同时引入各自的Co妹妹ent类显然是没有行的,代码会犯错,正在另外一个中央重写任何一个Co妹妹ent也会升高保护性。那这时候只能重构类名,我商定了一个定名规定,正在类名后面加之模块名,像这样:Article_Co妹妹ent、MessageBoard_Co妹妹ent

能够看到,名字变患上很长,那象征着当前应用Co妹妹ent的时分会写上更多的代码(至多字符多了)。而且,当前假如要对各个模块添加更多的一些整合性能,或许是相互挪用,发作重名的时分就需求重构名字。当然正在名目开端的时分就留意到这个成绩,并规则定名规定就能很好的防止这个成绩。另外一个处理办法能够思考应用定名空间。

注明:

本文提到的常量:PHP5.3开端const要害字能够用正在类的内部。const以及define都是用来申明常量的(它们的区分没有胪陈),然而正在定名空间里,define的作用是全局的,而const则作用于以后空间。我正在文中提到的常量是支使用const申明的常量。

根底:

定名空间将代码划分出没有同的空间(区域),每一个空间的常量、函数、类(为了偷懒,我下边都将它们称为元素)的名字互没有影响, 这个有点相似咱们经常提到的‘封装'的概念。

创立一个定名空间需求应用namespace要害字

代码以下:

<?php 
//创立一个名为'Article'的定名空间
namespace Article;
?>

要留意的是,以后剧本文件的第一个定名空间后面不克不及有任何代码,上面的写法都是谬误的:

代码以下:

//正在剧本后面写了一些逻辑代码
<?php
$path = "/";
class Co妹妹ent { }
namespace Article;
?>

或许以下:

//正在剧本后面输入了一些字符
<html></html>
<?php
namespace Article;
?>

为何要说第一个定名空间呢?由于同一剧本文件中能够创立多个定名空间。

上面我创立了两个定名空间,趁便为这两个空间各自增加了一个Co妹妹ent类元素:

代码以下:

<?php 
//创立一个名为'Article'的定名空间
namespace Article;
//此Co妹妹ent属于Article空间的元素
class Co妹妹ent { }

//创立一个名为'MessageBoard'的定名空间
namespace MessageBoard;
//此Co妹妹ent属于MessageBoard空间的元素
class Co妹妹ent { }
?>

正在没有同空间之间不成以间接挪用其它元素,需求应用定名空间的语法:

代码以下:

<?php 
namespace Article;
class Co妹妹ent { }

namespace MessageBoard;
class Co妹妹ent { }
//挪用以后空间(MessageBoard)的Co妹妹ent类
$co妹妹ent = new Co妹妹ent();
//挪用Article空间的Co妹妹ent类
$article_co妹妹ent = new \Article\Co妹妹ent();
?>

能够看到,正在MessageBoard空间中挪用article空间里的Co妹妹ent类时,应用了一种像文件门路的语法: \空间名\元素名

除了了类以外,对函数以及常量的用法是同样的,上面我为两个空间创立了新的元素,并正在MessageBoard空间中输入了它们的值。

代码以下:

<?php 
namespace Article;
const PATH = '/article';
function getCo妹妹entTotal() {
    return 100;
}
class Co妹妹ent { }

namespace MessageBoard;
const PATH = '/message_board';
function getCo妹妹entTotal() {
    return 300;
}
class Co妹妹ent { }
//挪用以后空间的常量、函数以及类
echo PATH; ///message_board
echo getCo妹妹entTotal(); //300
$co妹妹ent = new Co妹妹ent();
//挪用Article空间的常量、函数以及类
echo \Article\PATH; ///article
echo \Article\getCo妹妹entTotal(); //100
$article_co妹妹ent = new \Article\Co妹妹ent();
?>

子空间:

定名空间的挪用语法像文件门路同样是有情理的,它容许咱们自界说子空间来形容各个空间之间的关系。

抱愧我忘了说,article以及message board这两个模块其实都是处于同一个blog名目内。假如用定名空间来表白它们的关系

<?php 
//我用这样的定名空间示意处于blog下的article模块
namespace Blog\Article;
class Co妹妹ent { }

//我用这样的定名空间示意处于blog下的message board模块
namespace Blog\MessageBoard;
class Co妹妹ent { }
//挪用以后空间的类
$co妹妹ent = new Co妹妹ent();
//挪用Blog\Article空间的类
$article_co妹妹ent = new \Blog\Article\Co妹妹ent();
?>

公共空间

我有一个co妹妹on_inc.php剧本文件,外面有一些好用的函数以及类:

<?php 
function getIP() { }
class FilterXSS { }
?>

正在一个定名空间里引入这个剧本,剧本里的元素没有会归属到这个定名空间。假如这个剧本里不界说其它定名空间,它的元素就始终处于公共空间中:

<?php 
namespace Blog\Article;
//引入剧本文件
include './co妹妹on_inc.php';
$filter_XSS = new FilterXSS(); //呈现致命谬误:找没有到Blog\Article\FilterXSS类
$filter_XSS = new \FilterXSS(); //正确
?>

挪用公共空间的形式是间接正在元素称号前加 \ 就能够了,不然PHP解析器会以为我想挪用以后空间下的元素。除了了自界说的元素,还包罗PHP自带的元素,都属于公共空间

要提一下,其实公共空间的函数以及常量不必加 \ 也能够失常挪用(没有明确PHP为何要这样做),然而为了正确区别元素,仍是倡议挪用函数的时分加之 \

三、称号术语

正在说别号以及导入以前,需求晓得对于空间三种称号的术语,和PHP是怎么解析它们的。民间文档说患上十分好,我就间接拿来套了。

1.非限命名称,或没有蕴含前缀的类称号,例如 $co妹妹ent = new Co妹妹ent();。假如以后定名空间是Blog\Article,Co妹妹ent将被解析为Blog\Article\Co妹妹ent。假如应用Co妹妹ent的代码没有蕴含正在任何定名空间中的代码(全局空间中),则Co妹妹ent会被解析为Co妹妹ent。

2.限命名称,或蕴含前缀的称号,例如 $co妹妹ent = new Article\Co妹妹ent();。假如以后的定名空间是Blog,则Co妹妹ent会被解析为Blog\Article\Co妹妹ent。假如应用Co妹妹ent的代码没有蕴含正在任何定名空间中的代码(全局空间中),则Co妹妹ent会被解析为Co妹妹ent。

3.齐全限命名称,或蕴含了全局前缀操作符的称号,例如 $co妹妹ent = new \Article\Co妹妹ent();。正在这类状况下,Co妹妹ent老是被解析为代码中的文字名(literal name)Article\Co妹妹ent。

其实能够把这三种称号类比为文件名(例如 co妹妹ent.php)、绝对门路名(例如 ./article/co妹妹ent.php)、相对门路名(例如 /blog/article/co妹妹ent.php),这样可能会更易了解。

我用了几个示例来示意它们:

<?php 
//创立空间Blog
namespace Blog;
class Co妹妹ent { }
//非限命名称,示意以后Blog空间
//这个挪用将被解析成 Blog\Co妹妹ent();
$blog_co妹妹ent = new Co妹妹ent();
//限命名称,示意绝对于Blog空间
//这个挪用将被解析成 Blog\Article\Co妹妹ent();
$article_co妹妹ent = new Article\Co妹妹ent(); //类后面不反斜杆\
//齐全限命名称,示意相对于Blog空间
//这个挪用将被解析成 Blog\Co妹妹ent();
$article_co妹妹ent = new \Blog\Co妹妹ent(); //类后面有反斜杆\
//齐全限命名称,示意相对于Blog空间
//这个挪用将被解析成 Blog\Article\Co妹妹ent();
$article_co妹妹ent = new \Blog\Article\Co妹妹ent(); //类后面有反斜杆\

//创立Blog的子空间Article
namespace Blog\Article;
class Co妹妹ent { }
?>

别号以及导入
别号以及导入能够看做是挪用定名空间元素的一种快捷形式。PHP其实不支持导入函数或常量。

它们都是经过应用use操作符来完成

代码以下:

<?php 
namespace Blog\Article;
class Co妹妹ent { }

//创立一个BBS空间(我有筹算开个论坛)
namespace BBS;
//导入一个定名空间
use Blog\Article;
//导入定名空间后可以使用限命名称挪用元素
$article_co妹妹ent = new Article\Co妹妹ent();
//为定名空间应用别号
use Blog\Article as Arte;
//应用别号替代空间名
$article_co妹妹ent = new Arte\Co妹妹ent();
//导入一个类
use Blog\Article\Co妹妹ent;
//导入类后可以使用非限命名称挪用元素
$article_co妹妹ent = new Co妹妹ent();
//为类应用别号
use Blog\Article\Co妹妹ent as Comt;
//应用别号替代空间名
$article_co妹妹ent = new Comt();
?>

我留意到,假如导入元素的时分,以后空间有相反的名字元素将会怎么?显然后果会发作致命谬误。

<?php 
namespace Blog\Article;
class Co妹妹ent { }

namespace BBS;
class Co妹妹ent { }
Class Comt { }

//导入一个类
use Blog\Article\Co妹妹ent;
$article_co妹妹ent = new Co妹妹ent(); //与以后空间的Co妹妹ent发作抵触,顺序孕育发生致命谬误
//为类应用别号
use Blog\Article\Co妹妹ent as Comt;
$article_co妹妹ent = new Comt(); //与以后空间的Comt发作抵触,顺序孕育发生致命谬误
?>

静态挪用
PHP提供了namespace要害字以及__NAMESPACE__邪术常量静态的拜访元素,__NAMESPACE__能够经过组合字符串的方式来静态拜访

<?php 
namespace Blog\Article;
const PATH = '/Blog/article';
class Co妹妹ent { }

//namespace要害字示意以后空间
echo namespace\PATH; ///Blog/article
$co妹妹ent = new namespace\Co妹妹ent();
//邪术常量__NAMESPACE__的值是以后空间称号
echo __NAMESPACE__; //Blog\Article
//能够组分解字符串并挪用
$co妹妹ent_class_name = __NAMESPACE__ . '\Co妹妹ent';
$co妹妹ent = new $co妹妹ent_class_name();
?>

字符串方式挪用成绩:

下面的静态挪用的例子中,咱们看到了字符串方式的静态挪用形式,假如要应用这类形式要留意两个成绩

一、应用""时非凡字符可能被本义

<?php 
namespace Blog\Article;
class name { }
//我是想挪用Blog\Article\name
$class_name = __NAMESPACE__ . "\name"; //然而\n将被本义为换行符
$name = new $class_name(); //发作致命谬误
?>

二、没有会以为是限命名称

PHP正在编译剧本的时分就确定了元素所正在的空间,和导入的状况。而正在解析剧本时字符串方式挪用只能以为长短限命名称以及齐全限命名称,而永远不成能是限命名称

<?php 
namespace Blog;
//导入Co妹妹on类
use Blog\Article\Co妹妹on;
//我想应用非限命名称挪用Blog\Article\Co妹妹on
$co妹妹on_class_name = 'Co妹妹on';
//实际会被当做非限命名称,也就示意以后空间的Co妹妹on类,但我以后类不创立Co妹妹on类
$co妹妹on = new $co妹妹on_class_name(); //发作致命谬误:Co妹妹on类没有存正在
//我想应用限命名称挪用Blog\Article\Co妹妹on
$co妹妹on_class_name = 'Article\Co妹妹on';
//实际会被当做齐全限命名称,也就示意Article空间下的Co妹妹on类,但我上面只界说了Blog\Article空间而没有是Article空间
$co妹妹on = new $co妹妹on_class_name(); //发作致命谬误:Article\Co妹妹on类没有存正在

namespace Blog\Article;
class Co妹妹on { }
?>

总结
我对PHP的定名空间刚刚接触,也不克不及随意给一些不理论的倡议。我集体以为定名空间的作用以及性能都很弱小,假如要写插件或许通用库的时分不再用担忧重名成绩。不外假如名目进行到肯定水平,要经过添加定名空间去处理重名成绩,我感觉工作量没有会比重构名字少。也不能不抵赖它的语法会对名目添加肯定的复杂度,因而从名目一开端的时分就应该很好的布局它,并制订一个定名标准。

更多相干成绩请拜访PHP中文网:PHP视频教程

以上就是PHP——定名空间(namespace)应用具体引见的具体内容,更多请存眷资源魔其它相干文章!

标签: php开发教程 php开发资料 php开发自学 namespace

抱歉,评论功能暂时关闭!