백엔드 개발 PHP 튜토리얼 PHP命名空间(Namespace)的使用详解_php实例

PHP命名空间(Namespace)的使用详解_php实例

Jun 07, 2016 pm 05:24 PM
namespace PHP 네임스페이스

对于命名空间,官方文档已经说得很详细[查看],我在这里做了一下实践和总结。

命名空间一个最明确的目的就是解决重名问题,PHP中不允许两个函数或者类出现相同的名字,否则会产生一个致命的错误。这种情况下只要避免命名重复就可以解决,最常见的一种做法是约定一个前缀。

例:项目中有两个模块:article和message board,它们各自有一个处理用户留言的类Comment。之后我可能想要增加对所有用户留言的一些信息统计功能,比如说我想得到所有留言的数量。这时候调用它们Comment提供的方法是很好的做法,但是同时引入各自的Comment类显然是不行的,代码会出错,在另一个地方重写任何一个Comment也会降低维护性。那这时只能重构类名,我约定了一个命名规则,在类名前面加上模块名,像这样:Article_Comment、MessageBoard_Comment

可以看到,名字变得很长,那意味着以后使用Comment的时候会写上更多的代码(至少字符多了)。并且,以后如果要对各个模块增加更多的一些整合功能,或者是互相调用,发生重名的时候就需要重构名字。当然在项目开始的时候就注意到这个问题,并规定命名规则就能很好的避免这个问题。另一个解决方法可以考虑使用命名空间。


注明:

本文提到的常量:PHP5.3开始const关键字可以用在类的外部。const和define都是用来声明常量的(它们的区别不详述),但是在命名空间里,define的作用是全局的,而const则作用于当前空间。我在文中提到的常量是指使用const声明的常量。


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

创建一个命名空间需要使用namespace关键字,这样:

复制代码 代码如下:

//创建一个名为'Article'的命名空间
namespace Article;

?>


要注意的是,当前脚本文件的第一个命名空间前面不能有任何代码,下面的写法都是错误的:
复制代码 代码如下:

//例一
//在脚本前面写了一些逻辑代码

$path = "/";

class Comment { }

namespace Article;

?>

 

//例二
//在脚本前面输出了一些字符


namespace Article;

?>


为什么要说第一个命名空间呢?因为同一脚本文件中可以创建多个命名空间。

下面我创建了两个命名空间,顺便为这两个空间各自添加了一个Comment类元素:

复制代码 代码如下:

//创建一个名为'Article'的命名空间
namespace Article;

//此Comment属于Article空间的元素
class Comment { }


//创建一个名为'MessageBoard'的命名空间
namespace MessageBoard;

//此Comment属于MessageBoard空间的元素
class Comment { }
?>


在不同空间之间不可以直接调用其它元素,需要使用命名空间的语法:
复制代码 代码如下:

namespace Article;

class Comment { }


namespace MessageBoard;

class Comment { }

//调用当前空间(MessageBoard)的Comment类
$comment = new Comment();

//调用Article空间的Comment类
$article_comment = new \Article\Comment();

?>


可以看到,在MessageBoard空间中调用article空间里的Comment类时,使用了一种像文件路径的语法: \空间名\元素名

除了类之外,对函数和常量的用法是一样的,下面我为两个空间创建了新的元素,并在MessageBoard空间中输出了它们的值。

复制代码 代码如下:

namespace Article;

const PATH = '/article';

function getCommentTotal() {
    return 100;
}

class Comment { }


namespace MessageBoard;

const PATH = '/message_board';

function getCommentTotal() {
    return 300;
}

class Comment { }

//调用当前空间的常量、函数和类
echo PATH; ///message_board
echo getCommentTotal(); //300
$comment = new Comment();

//调用Article空间的常量、函数和类
echo \Article\PATH; ///article
echo \Article\getCommentTotal(); //100
$article_comment = new \Article\Comment();

?>


然后我的确得到了Article空间的元素数据。


子空间
命名空间的调用语法像文件路径一样是有道理的,它允许我们自定义子空间来描述各个空间之间的关系。

抱歉我忘了说,article和message board这两个模块其实都是处于同一个blog项目内。如果用命名空间来表达它们的关系,是这样:

复制代码 代码如下:

//我用这样的命名空间表示处于blog下的article模块
namespace Blog\Article;

class Comment { }


//我用这样的命名空间表示处于blog下的message board模块
namespace Blog\MessageBoard;

class Comment { }

//调用当前空间的类
$comment = new Comment();

//调用Blog\Article空间的类
$article_comment = new \Blog\Article\Comment();

?>


而且,子空间还可以定义很多层次,比如说 Blog\Article\Archives\Date


公共空间
我有一个common_inc.php脚本文件,里面有一些好用的函数和类:

复制代码 代码如下:

function getIP() { }

class FilterXSS { }

?>


在一个命名空间里引入这个脚本,脚本里的元素不会归属到这个命名空间。如果这个脚本里没有定义其它命名空间,它的元素就始终处于公共空间中:
复制代码 代码如下:

namespace Blog\Article;

//引入脚本文件
include './common_inc.php';

$filter_XSS = new FilterXSS(); //出现致命错误:找不到Blog\Article\FilterXSS类

$filter_XSS = new \FilterXSS(); //正确

?>


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

要提一下,其实公共空间的函数和常量不用加 \ 也可以正常调用(不明白PHP为什么要这样做),但是为了正确区分元素,还是建议调用函数的时候加上 \


名称术语
在说别名和导入之前,需要知道关于空间三种名称的术语,以及PHP是怎样解析它们的。官方文档说得非常好,我就直接拿来套了。

1.非限定名称,或不包含前缀的类名称,例如 $comment = new Comment();。如果当前命名空间是Blog\Article,Comment将被解析为Blog\Article\Comment。如果使用Comment的代码不包含在任何命名空间中的代码(全局空间中),则Comment会被解析为Comment。

2.限定名称,或包含前缀的名称,例如 $comment = new Article\Comment();。如果当前的命名空间是Blog,则Comment会被解析为Blog\Article\Comment。如果使用Comment的代码不包含在任何命名空间中的代码(全局空间中),则Comment会被解析为Comment。

3.完全限定名称,或包含了全局前缀操作符的名称,例如 $comment = new \Article\Comment();。在这种情况下,Comment总是被解析为代码中的文字名(literal name)Article\Comment。
 

其实可以把这三种名称类比为文件名(例如 comment.php)、相对路径名(例如 ./article/comment.php)、绝对路径名(例如 /blog/article/comment.php),这样可能会更容易理解。

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

复制代码 代码如下:

//创建空间Blog
namespace Blog;

class Comment { }

//非限定名称,表示当前Blog空间
//这个调用将被解析成 Blog\Comment();
$blog_comment = new Comment();

//限定名称,表示相对于Blog空间
//这个调用将被解析成 Blog\Article\Comment();
$article_comment = new Article\Comment(); //类前面没有反斜杆\

//完全限定名称,表示绝对于Blog空间
//这个调用将被解析成 Blog\Comment();
$article_comment = new \Blog\Comment(); //类前面有反斜杆\

//完全限定名称,表示绝对于Blog空间
//这个调用将被解析成 Blog\Article\Comment();
$article_comment = new \Blog\Article\Comment(); //类前面有反斜杆\


//创建Blog的子空间Article
namespace Blog\Article;

class Comment { }

?>


其实之前我就一直在使用非限定名称和完全限定名称,现在它们终于可以叫出它们的名称了。


别名和导入
别名和导入可以看作是调用命名空间元素的一种快捷方式。PHP并不支持导入函数或常量。

它们都是通过使用use操作符来实现:

复制代码 代码如下:

namespace Blog\Article;

class Comment { }


//创建一个BBS空间(我有打算开个论坛)
namespace BBS;

//导入一个命名空间
use Blog\Article;
//导入命名空间后可使用限定名称调用元素
$article_comment = new Article\Comment();

//为命名空间使用别名
use Blog\Article as Arte;
//使用别名代替空间名
$article_comment = new Arte\Comment();

//导入一个类
use Blog\Article\Comment;
//导入类后可使用非限定名称调用元素
$article_comment = new Comment();

//为类使用别名
use Blog\Article\Comment as Comt;
//使用别名代替空间名
$article_comment = new Comt();

?>


我注意到,如果导入元素的时候,当前空间有相同的名字元素将会怎样?显然结果会发生致命错误。

例:

复制代码 代码如下:

namespace Blog\Article;

class Comment { }


namespace BBS;

class Comment { }

Class Comt { }


//导入一个类
use Blog\Article\Comment;
$article_comment = new Comment(); //与当前空间的Comment发生冲突,程序产生致命错误

//为类使用别名
use Blog\Article\Comment as Comt;
$article_comment = new Comt(); //与当前空间的Comt发生冲突,程序产生致命错误

?>


动态调用
PHP提供了namespace关键字和__NAMESPACE__魔法常量动态的访问元素,__NAMESPACE__可以通过组合字符串的形式来动态访问:
复制代码 代码如下:

namespace Blog\Article;

const PATH = '/Blog/article';

class Comment { }


//namespace关键字表示当前空间
echo namespace\PATH; ///Blog/article
$comment = new namespace\Comment();

//魔法常量__NAMESPACE__的值是当前空间名称
echo __NAMESPACE__; //Blog\Article
//可以组合成字符串并调用
$comment_class_name = __NAMESPACE__ . '\Comment';
$comment = new $comment_class_name();

?>


字符串形式调用问题

上面的动态调用的例子中,我们看到了字符串形式的动态调用方式,如果要使用这种方式要注意两个问题。

1. 使用双引号的时候特殊字符可能被转义

复制代码 代码如下:

namespace Blog\Article;

class name { }

//我是想调用Blog\Article\name
$class_name = __NAMESPACE__ . "\name"; //但是\n将被转义为换行符

$name = new $class_name(); //发生致命错误

?>


2. 不会认为是限定名称

PHP在编译脚本的时候就确定了元素所在的空间,以及导入的情况。而在解析脚本时字符串形式调用只能认为是非限定名称和完全限定名称,而永远不可能是限定名称。

复制代码 代码如下:

namespace Blog;

//导入Common类
use Blog\Article\Common;
//我想使用非限定名称调用Blog\Article\Common
$common_class_name = 'Common';
//实际会被当作非限定名称,也就表示当前空间的Common类,但我当前类没有创建Common类
$common = new $common_class_name(); //发生致命错误:Common类不存在

//我想使用限定名称调用Blog\Article\Common
$common_class_name = 'Article\Common';
//实际会被当作完全限定名称,也就表示Article空间下的Common类,但我下面只定义了Blog\Article空间而不是Article空间
$common = new $common_class_name(); //发生致命错误:Article\Common类不存在


namespace Blog\Article;

class Common { }

?>


总结
我对PHP的命名空间刚刚接触,也不能随便给一些没有实践的建议。我个人认为命名空间的作用和功能都很强大,如果要写插件或者通用库的时候再也不用担心重名问题。不过如果项目进行到一定程度,要通过增加命名空间去解决重名问题,我觉得工作量不会比重构名字少。也不得不承认它的语法会对项目增加一定的复杂度,因此从项目一开始的时候就应该很好的规划它,并制定一个命名规范。
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

PHP8.0의 네임스페이스 병합 PHP8.0의 네임스페이스 병합 May 14, 2023 am 08:43 AM

지속적인 기술 개발로 인해 PHP 언어는 지속적으로 업데이트되고 개선되고 있습니다. PHP 언어의 최신 버전인 PHP8.0은 이전 버전보다 더욱 강력해졌습니다. 중요한 기능 중 하나는 네임스페이스 병합입니다. 그렇다면 네임스페이스 병합이란 무엇입니까? 그것의 용도는 무엇입니까? 이에 대해서는 아래에서 자세히 논의해 보겠습니다. 네임스페이스는 서로 다른 코드를 구별하는 데 사용되는 PHP의 네임스페이스로, 코드에서 동일한 이름을 가진 클래스, 함수 또는 상수를 사용할 수 있습니다. 이전 버전에서는

스티커 메모 이름 공간을 제거하는 방법 스티커 메모 이름 공간을 제거하는 방법 Dec 27, 2023 pm 01:51 PM

win7 시스템을 사용하면 스티커 메모 도구를 찾을 수 있습니다. Stickynotes는 실제로 전자 메모장처럼 작동합니다. 단어를 삭제하려면 제어판에서 제거해야 합니다. StickyNotes 네임스페이스란 무엇이며 어떻게 삭제합니까? 방법 1: 찾기 - 방법 2: 나중에 삭제를 클릭합니다. 방법 3: 타사 소프트웨어를 사용하여 제공되는 StickyNotes 도구입니다. 데스크탑에 떠다니는 스티커 메모와 유사한 시스템으로 사용자가 중요한 사항을 적어두는 것이 편리합니다. 일반적으로 소프트웨어는 숨겨진 상태에 있으며 필요한 경우 지정된 시간에 튀어 나와 사용자에게 알림을 보낼 수 있습니다.

PHP 네임스페이스 로딩 오류를 처리하고 관련 오류 프롬프트를 생성하는 방법 PHP 네임스페이스 로딩 오류를 처리하고 관련 오류 프롬프트를 생성하는 방법 Aug 07, 2023 am 11:37 AM

PHP 네임스페이스 로딩 오류를 처리하고 관련 오류 프롬프트를 생성하는 방법 PHP 개발에서 네임스페이스는 코드를 구성 및 관리하고 이름 지정 충돌을 방지하는 데 도움이 됩니다. 하지만 네임스페이스를 사용할 때 가끔 로딩 오류가 발생하는 경우가 있습니다. 이러한 오류는 잘못된 네임스페이스 정의 또는 로드된 파일의 잘못된 경로로 인해 발생할 수 있습니다. 이 문서에서는 몇 가지 일반적인 네임스페이스 로딩 오류를 소개하고 해당 처리 방법을 제공하며 관련 오류 프롬프트를 생성하는 방법을 설명합니다. 1. 네임스페이스 결정

PHP에서 네임스페이스 사용에 대한 팁 PHP에서 네임스페이스 사용에 대한 팁 May 27, 2023 am 11:01 AM

PHP의 발전과 함께 코드의 양은 계속 증가하고 있으며, 코드의 조직적 구조는 점점 더 중요해지고 있습니다. PHP를 사용할 때 네임스페이스는 코드를 더 잘 구성하고 이름 충돌과 같은 문제를 해결하며 코드의 가독성과 유지 관리성을 향상시키는 데 도움이 되는 매우 중요한 개념입니다. 이 글에서는 PHP에서 네임스페이스를 사용하는 방법과 몇 가지 일반적인 사용 팁을 소개합니다. 1. 네임스페이스의 기본 개념 네임스페이스는 관련 클래스, 인터페이스, 함수 등을 구성하는 방법입니다. PHP에서 네임스페이스는 "n"이라는 키워드를 사용합니다.

PHP 네임스페이스 및 FAQ를 사용하는 방법 PHP 네임스페이스 및 FAQ를 사용하는 방법 Jun 09, 2023 am 08:15 AM

PHP 언어의 발전과 함께 네임스페이스 개념이 점차 PHP에 도입되었습니다. 네임스페이스는 이름 충돌과 코드 혼동을 피하기 위해 코드 구조를 구성하는 방법입니다. 이 글에서는 PHP 네임스페이스를 사용하는 방법과 자주 묻는 질문에 답변하는 방법을 살펴보겠습니다. 1. 네임스페이스 정의 네임스페이스는 개발자가 코드를 더 잘 구성할 수 있도록 하는 PHP5.3에 도입된 새로운 기능입니다. 네임스페이스는 식별자입니다(식별자

PHP 객체 지향 프로그래밍에서 네임스페이스 분석 PHP 객체 지향 프로그래밍에서 네임스페이스 분석 Aug 10, 2023 pm 02:12 PM

PHP는 웹 개발에 널리 사용되는 매우 일반적으로 사용되는 스크립팅 언어입니다. 프로젝트의 규모가 커질수록 코드의 복잡성도 증가합니다. 코드를 더 잘 관리하고 구성하기 위해 PHP는 네임스페이스 개념을 도입합니다. 이 기사에서는 PHP 객체 지향 프로그래밍의 네임스페이스를 분석하고 해당 코드 예제를 제공합니다. 네임스페이스의 개념 네임스페이스는 파일 시스템에서 폴더(디렉토리)의 역할과 유사하게 코드를 논리적으로 그룹화하는 메커니즘입니다. 서로 다른 클래스 간의 이름 충돌을 방지합니다.

PHP7의 NameSpace 및 Use 키워드를 사용하여 코드 구조를 구성하는 방법은 무엇입니까? PHP7의 NameSpace 및 Use 키워드를 사용하여 코드 구조를 구성하는 방법은 무엇입니까? Oct 19, 2023 am 08:07 AM

PHP7의 NameSpace 및 Use 키워드를 사용하여 코드 구조를 구성하는 방법은 무엇입니까? 소개: 소프트웨어 개발에서 코드의 조직적 구조는 코드의 가독성, 유지 관리성 및 확장성과 직접적인 관련이 있습니다. PHP 버전이 지속적으로 반복되면서 PHP7에서는 더 많은 유연성과 편의성을 제공하는 NameSpace 및 Use 키워드를 도입했습니다. 이 기사에서는 PHP7의 NameSpace 및 Use 키워드를 사용하여 코드 구조를 구성하고 특정 코드를 제공하는 방법을 소개합니다.

PHP에서 네임스페이스를 사용하여 사용자 정의 데이터 유형을 관리하고 조작하는 방법 PHP에서 네임스페이스를 사용하여 사용자 정의 데이터 유형을 관리하고 조작하는 방법 Jul 18, 2023 pm 12:00 PM

PHP에서 네임스페이스를 사용하여 사용자 정의 데이터 유형을 관리하고 조작하는 방법 PHP에서 네임스페이스는 이름 충돌을 해결하고 코드를 구성하는 데 사용되는 메커니즘입니다. 네임스페이스를 사용하면 관련 클래스, 인터페이스, 함수 및 상수를 특정 네임스페이스로 분류하여 더 나은 코드 구성 및 관리를 달성할 수 있습니다. 이 기사에서는 네임스페이스를 사용하여 사용자 정의 데이터 유형을 관리하고 조작하는 방법에 중점을 둘 것입니다. 구체적인 단계는 코드 예시를 통해 자세히 설명하겠습니다. 먼저, 이름이 지정된

See all articles