Основы пространств имён
(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 ¶17 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 ¶10 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 ¶13 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 ¶13 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 ¶14 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;}
?>