首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

FAQ: things you need to know about namespaces

(PHP 5 >= 5.3.0, PHP 7)

This FAQ is split into two sections: common questions, and some specifics of implementation that are helpful to understand fully.

First, the common questions.

  1. If I don't use namespaces, should I care about any of this?
  1. How do I use internal or global classes in a namespace?
  1. How do I use namespaces classes functions, or constants in their own namespace?
  1. How does a name like \my\name or \name resolve?
  1. How does a name like my\name resolve?
  1. How does an unqualified class name like name resolve?
  1. How does an unqualified function name or unqualified constant name like name resolve?

There are a few implementation details of the namespace implementations that are helpful to understand.

  1. Import names cannot conflict with classes defined in the same file.
  1. Nested namespaces are not allowed.
  1. Before PHP 5.6 neither functions nor constants can be imported via the use statement.
  1. Dynamic namespace names (quoted identifiers) should escape backslash.
  1. Undefined Constants referenced using any backslash die with fatal error
  1. Cannot override special constants NULL, TRUE, FALSE, ZEND_THREAD_SAFE or ZEND_DEBUG_BUILD

If I don't use namespaces, should I care about any of this?

No. Namespaces do not affect any existing code in any way, or any as-yet-to-be-written code that does not contain namespaces. You can write this code if you wish:

Example #1 Accessing global classes outside a namespace

代码语言:javascript
复制
<?php
$a?=?new?\stdClass;
?>

This is functionally equivalent to:

Example #2 Accessing global classes outside a namespace

代码语言:javascript
复制
<?php
$a?=?new?stdClass;
?>

How do I use internal or global classes in a namespace?

Example #3 Accessing internal classes in namespaces

代码语言:javascript
复制
<?php
namespace?foo;
$a?=?new?\stdClass;

function?test(\ArrayObject?$typehintexample?=?null)?{}

$a?=?\DirectoryIterator::CURRENT_AS_FILEINFO;

//?extending?an?internal?or?global?class
class?MyException?extends?\Exception?{}
?>

How do I use namespaces classes, functions, or constants in their own namespace?

Example #4 Accessing internal classes, functions or constants in namespaces

代码语言:javascript
复制
<?php
namespace?foo;

class?MyClass?{}

//?using?a?class?from?the?current?namespace?as?a?type?hint
function?test(MyClass?$typehintexample?=?null)?{}
//?another?way?to?use?a?class?from?the?current?namespace?as?a?type?hint
function?test(\foo\MyClass?$typehintexample?=?null)?{}

//?extending?a?class?from?the?current?namespace
class?Extended?extends?MyClass?{}

//?accessing?a?global?function
$a?=?\globalfunc();

//?accessing?a?global?constant
$b?=?\INI_ALL;
?>

How does a name like \my\name or \name resolve?

Names that begin with a _ always resolve to what they look like, so \my\name is in fact _my\name, and \Exception is Exception.

Example #5 Fully Qualified names

代码语言:javascript
复制
<?php
namespace?foo;
$a?=?new?\my\name();?//?instantiates?"my\name"?class
echo?\strlen('hi');?//?calls?function?"strlen"
$a?=?\INI_ALL;?//?$a?is?set?to?the?value?of?constant?"INI_ALL"
?>

How does a name like my\name resolve?

Names that contain a backslash but do not begin with a backslash like my\name can be resolved in 2 different ways.

If there is an import statement that aliases another name to my, then the import alias is applied to the my in my\name.

Otherwise, the current namespace name is prepended to my\name.

Example #6 Qualified names

代码语言:javascript
复制
<?php
namespace?foo;
use?blah\blah?as?foo;

$a?=?new?my\name();?//?instantiates?"foo\my\name"?class
foo\bar::name();?//?calls?static?method?"name"?in?class?"blah\blah\bar"
my\bar();?//?calls?function?"foo\my\bar"
$a?=?my\BAR;?//?sets?$a?to?the?value?of?constant?"foo\my\BAR"
?>

How does an unqualified class name like name resolve?

Class names that do not contain a backslash like name can be resolved in 2 different ways.

If there is an import statement that aliases another name to name, then the import alias is applied.

Otherwise, the current namespace name is prepended to name.

Example #7 Unqualified class names

代码语言:javascript
复制
<?php
namespace?foo;
use?blah\blah?as?foo;

$a?=?new?name();?//?instantiates?"foo\name"?class
foo::name();?//?calls?static?method?"name"?in?class?"blah\blah"
?>

How does an unqualified function name or unqualified constant name like name resolve?

Function or constant names that do not contain a backslash like name can be resolved in 2 different ways.

First, the current namespace name is prepended to name.

Finally, if the constant or function name does not exist in the current namespace, a global constant or function name is used if it exists.

Example #8 Unqualified function or constant names

代码语言:javascript
复制
<?php
namespace?foo;
use?blah\blah?as?foo;

const?FOO?=?1;

function?my()?{}
function?foo()?{}
function?sort(&$a)
{
????\sort($a);?//?calls?the?global?function?"sort"
????$a?=?array_flip($a);
????return?$a;
}

my();?//?calls?"foo\my"
$a?=?strlen('hi');?//?calls?global?function?"strlen"?because?"foo\strlen"?does?not?exist
$arr?=?array(1,3,2);
$b?=?sort($arr);?//?calls?function?"foo\sort"
$c?=?foo();?//?calls?function?"foo\foo"?-?import?is?not?applied

$a?=?FOO;?//?sets?$a?to?value?of?constant?"foo\FOO"?-?import?is?not?applied
$b?=?INI_ALL;?//?sets?$b?to?value?of?global?constant?"INI_ALL"
?>

Import names cannot conflict with classes defined in the same file.

The following script combinations are legal:

file1.php

代码语言:javascript
复制
<?php
namespace?my\stuff;
class?MyClass?{}
?>

another.php

代码语言:javascript
复制
<?php
namespace?another;
class?thing?{}
?>

file2.php

代码语言:javascript
复制
<?php
namespace?my\stuff;
include?'file1.php';
include?'another.php';

use?another\thing?as?MyClass;
$a?=?new?MyClass;?//?instantiates?class?"thing"?from?namespace?another
?>

There is no name conflict, even though the class MyClass exists within the my\stuff namespace, because the MyClass definition is in a separate file. However, the next example causes a fatal error on name conflict because MyClass is defined in the same file as the use statement.

代码语言:javascript
复制
<?php
namespace?my\stuff;
use?another\thing?as?MyClass;
class?MyClass?{}?//?fatal?error:?MyClass?conflicts?with?import?statement
$a?=?new?MyClass;
?>

Nested namespaces are not allowed.

PHP does not allow nesting namespaces

代码语言:javascript
复制
<?php
namespace?my\stuff?{
????namespace?nested?{
????????class?foo?{}
????}
}
?>

However, it is easy to simulate nested namespaces like so:

代码语言:javascript
复制
<?php
namespace?my\stuff\nested?{
????class?foo?{}
}
?>

Before PHP 5.6 neither functions nor constants can be imported via the use statement.

Before PHP 5.6 the only elements that are affected by use statements are namespaces and class names. In order to shorten a long constant or function, import its containing namespace.

代码语言:javascript
复制
<?php
namespace?mine;
use?ultra\long\ns\name;

$a?=?name\CONSTANT;
name\func();
?>

As of PHP 5.6 aliasing or importing function and constant names is allowed.

Dynamic namespace names (quoted identifiers) should escape backslash

It is very important to realize that because the backslash is used as an escape character within strings, it should always be doubled when used inside a string. Otherwise there is a risk of unintended consequences:

Example #9 Dangers of using namespaced names inside a double-quoted string

代码语言:javascript
复制
<?php
$a?=?"dangerous\name";?//?\n?is?a?newline?inside?double?quoted?strings!
$obj?=?new?$a;

$a?=?'not\at\all\dangerous';?//?no?problems?here.
$obj?=?new?$a;
?>

Inside a single-quoted string, the backslash escape sequence is much safer to use, but it is still recommended practice to escape backslashes in all strings as a best practice.

Undefined Constants referenced using any backslash die with fatal error

Any undefined constant that is unqualified like FOO will produce a notice explaining that PHP assumed FOO was the value of the constant. Any constant, qualified or fully qualified, that contains a backslash will produce a fatal error if not found.

Example #10 Undefined constants

代码语言:javascript
复制
<?php
namespace?bar;
$a?=?FOO;?//?produces?notice?-?undefined?constants?"FOO"?assumed?"FOO";
$a?=?\FOO;?//?fatal?error,?undefined?namespace?constant?FOO
$a?=?Bar\FOO;?//?fatal?error,?undefined?namespace?constant?bar\Bar\FOO
$a?=?\Bar\FOO;?//?fatal?error,?undefined?namespace?constant?Bar\FOO
?>

Cannot override special constants NULL, TRUE, FALSE, ZEND_THREAD_SAFE or ZEND_DEBUG_BUILD

Any attempt to define a namespaced constant that is a special, built-in constant results in a fatal error

Example #11 Undefined constants

代码语言:javascript
复制
<?php
namespace?bar;
const?NULL?=?0;?//?fatal?error;
const?true?=?'stupid';?//?also?fatal?error;
//?etc.
?>

← Name resolution rules

Errors →

代码语言:txt
复制
 ? 1997–2017 The PHP Documentation Group

Licensed under the Creative Commons Attribution License v3.0 or later.

扫码关注腾讯云开发者

领取腾讯云代金券

http://www.vxiaotou.com