Использование пространства имён: основы
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
До обсуждения использования пространств имён важно понять, как PHP узнает,
какие элементы из пространства имён запрашиваются в вашем коде. Можно провести
аналогию между пространствами имён PHP и файловой системой. Есть три способа обратиться
к файлу в файловой системе:
-
Относительное имя файла, такое как
foo.txt
, преобразуемое в
currentdirectory/foo.txt
, где currentdirectory
- текущая
директория, в которой мы находимся. Тогда, если текущая директория
/home/foo
, то имя преобразуется в /home/foo/foo.txt
.
-
Относительное имя пути, такое как
subdirectory/foo.txt
, преобразуется
в currentdirectory/subdirectory/foo.txt
.
-
Абсолютное имя пути, такое как
/main/foo.txt
, которое остаётся
таким же: /main/foo.txt
.
Тот же принцип применим и к элементам из пространств имён PHP. Например,
имя класса может быть указано тремя способами:
-
Неполные имена (имена классов без префикса), такие как
$a = new foo();
или
foo::staticmethod();
. Если текущее пространство имён
currentnamespace
, то эти имена преобразуются в
currentnamespace\foo
. Если код находится в глобальном
пространстве имён, то имена остаются такими же: foo
.
Предупреждение: неполные имена для функций и констант будут определяться
в глобальном пространстве имён, если они не определены в текущем пространстве имён.
Подробнее в Использование пространств
имён: доступ к глобальным функциям и классам.
-
Полные имена (имена классов с префиксами), такие как
$a = new subnamespace\foo();
или
subnamespace\foo::staticmethod();
. Если текущее пространство имён
currentnamespace
, то эти имена преобразуются в
currentnamespace\subnamespace\foo
. Если
код находится в глобальном пространстве имён, то имена преобразуются в subnamespace\foo
.
-
Абсолютные имена или имена с предшествующим префиксом, обозначающим глобальное
пространство.
$a = new \currentnamespace\foo();
или
\currentnamespace\foo::staticmethod();
. Имена всегда
определяются так же, как и записаны: currentnamespace\foo
.
Ниже приведён пример трёх вариантов синтаксиса в реальном коде:
Обратите внимание, что для доступа к любым глобальным
классам, функциям или константам, может использоваться абсолютное имя, такое как
\strlen(), или \Exception, или
\INI_ALL
.
Пример #1 Доступ к глобальным классам, функциям и константам из пространства имён
<?php
namespace Foo;
function strlen() {}
const INI_ALL = 3;
class Exception {}
$a = \strlen('hi'); // вызывает глобальную функцию strlen
$b = \INI_ALL; // получает доступ к глобальной константе INI_ALL
$c = new \Exception('error'); // Создаёт экземпляр глобального класса Exception
?>
richard at richard-sumilang dot com ¶15 years ago
Syntax for extending classes in namespaces is still the same.
Lets call this Object.php:
<?php
namespace com\rsumilang\common;
class Object{
}
?>
And now lets create a class called String that extends object in String.php:
<?php
class String extends com\rsumilang\common\Object{
}
?>
Now if you class String was defined in the same namespace as Object then you don't have to specify a full namespace path:
<?php
namespace com\rsumilang\common;
class String extends Object
{
}
?>
Lastly, you can also alias a namespace name to use a shorter name for the class you are extending incase your class is in seperate namespace:
<?php
namespace com\rsumilang\util;
use com\rsumlang\common as Common;
class String extends Common\Object
{
}
?>
- Richard Sumilang
Anonymous ¶9 years ago
<?php
namespace Foo;
try {
}
catch (Exception as $ex) {
}
?>
Instead use fully qualified name for the exception to catch it
<?php
namespace Foo;
try {
}
catch (\Exception as $ex) {
}
?>
Lukas Z ¶11 years ago
Well variables inside namespaces do not override others since variables are never affected by namespace but always global:
"Although any valid PHP code can be contained within a namespace, only four types of code are affected by namespaces: classes, interfaces, functions and constants. "
Source: "Defining Namespaces"
http://www.php.net/manual/en/language.namespaces.definition.php
tom at tomwardrop dot com ¶11 years ago
It seems the file system analogy only goes so far. One thing that's missing that would be very useful is relative navigation up the namespace chain, e.g.
<?php
namespace MyProject {
class Person {}
}
namespace MyProject\People {
class Adult extends ..\Person {}
}
?>
That would be really nice, especially if you had really deep namespaces. It would save you having to type out the full namespace just to reference a resource one level up.
philip dot preisser at arcor dot de ¶12 years ago
Working with variables can overwrite equal variables in other namespaces
<?php namespace
main
{}
namespace
main\sub1
{
$data = 1;
}
namespace
main\sub2
{
echo $data;$data = 2;
}
namespace
main\sub1
{
echo $data;$data = 1;
}
namespace
{
echo $data;}
?>
Franois Vespa ¶12 years ago
It seems you cannot nest a constant declaration within a if statement
<?php
namespace FOO;
if(eval)
const BAR=true;
if(eval)
define('FOO\BAR',true);
?>