Пространства имен
Пространства имен позволяют избежать конфликта имен и сгруппировать функционал. Внутри пространства имен могут быть размещены классы, интерфейсы, функции и константы.
Если какая-та конструкция (например, класс или функция) определена вне любого пространства имен, то считается, что она расположена в глобальном пространстве имен.
Определение пространства имен
Для создания пространства имен применяется директива namespace
, после которой идет название пространства имен:
namespace base;
class Person {
private $name;
function __construct($name) {
$this->name = $name;
}
}
В данном случае определено пространство имен base
. Обычно названия пространств указываются в нижнем регистре. Все, что расположено ниже этой директивы, относится к пространству имен base
. То есть класс Person
принадлежит пространству имен base
.
Стоит учитывать, что определение пространства имен должно быть расположено выше любого другого кода или разметки html
:
<?
namespace base;
class Person {
public $name;
function __construct($name) {
$this->name = $name;
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title>METANIT.COM</title>
<meta charset="utf-8" />
</head>
<body>
<?
$tom = new Person("Tom");
echo $tom->name;
?>
</body>
</html>
Обращение к пространству имен
Для обращения к конструкциям из пространства имен перед названием конструкции через слеш указывается ее пространство имен. Например, у нас есть файл Person.php
:
<?
namespace base;
class Person {
public $name;
function __construct($name) {
$this->name = $name;
}
}
Теперь в другом файле подключим этот файл и обратимся к классу Person
:
<?
namespace work;
include "Person.php";
$tom = new \base\Person("Tom");
echo $tom->name;
Здесь определено другое пространство имен - work
. Сначала в нем подключается файл Person.php
. Затем создаем объект класса Person
.
Если конструкции одного пространства имен используются в другом пространстве имен (в том числе в глобальном пространстве имен), то перед названием конструкции указывается название ее пространства имен. Так, поскольку класс Person
расположен в другом пространстве имен - base
, то перед названием класса указываем его полное имя с учетом его пространства имен:
$tom = new \base\Person("Tom");
Обратите внимание, что сначала идет слеш, потом название пространства имен и потом через слеш название класса (\base\Person
).
Без указания пространства имен мы можем использовать конструкцию только в том же пространстве имен, в котором она определена.
Вложенные пространства имен
Одни пространства имен могут содержать другие:
<?
namespace base\classes;
class Person {
public $name;
function __construct($name) {
$this->name = $name;
}
}
Здесь класс Person
определен в пространстве имен base\classes\
. То есть теперь для обращения к классу Person
в другом пространстве имен надо указывать \base\classes\Person
:
<?
namespace work;
include "Person.php";
$tom = new \base\classes\Person("Tom");
echo $tom->name;
Псевдонимы
Если в одном пространстве имен используется какой-то класс из другого пространства имен, то писать каждый раз полное имя класса с учетом его пространства имен может быть утомительно, кроме того, перегружает код:
<?
namespace work;
include "Person.php";
$tom = new \base\classes\Person("Tom");
echo $tom->name . "<br>";
$bob = new \base\classes\Person("Bob");
echo $bob->name;
В этом случае мы можем использовать псевдонимы, которые задаются в виде:
use полное_имя_класса as псевдоним;
Конструкция use
импортирует класс из другого пространства имен, а оператор as
устанавливает для него псевдоним.
Так, сократим предыдущий код с помощью псевдонимов:
<?
namespace work;
include "Person.php";
// установка псевдонима
use \base\classes\Person as User;
$tom = new User("Tom");
echo $tom->name . "<br>";
$bob = new User("Bob");
echo $bob->name;
В данном случае для класса \base\classes\Person
установлен псевдоним User
, соответственно теперь для обращения к классу Person мы можем использовать его псевдоним User
. Результат тот же, но кода меньше.
Можно использовать только конструкцию use
без указания псевдонима. Тогда класс можно будет исользовать по его непосредственному имени:
<?
namespace work;
include "Person.php";
use \base\classes\Person;
$tom = new Person("Tom");
echo $tom->name . "<br>";
$bob = new Person("Bob");
echo $bob->name;
Подключение множества классов
Подобным образом можно подключать сразу несколько классов. Например, пусть в файле Person.php
имеются следующие классы:
<?
namespace base\classes;
class Person {
public $name;
function __construct($name) {
$this->name = $name;
}
}
class Employee extends Person { }
Подключение классов Person
и Employee
:
<?
namespace work;
include "Person.php";
use \base\classes\Person as User, \base\classes\Employee as Employee;
$tom = new User("Tom");
echo $tom->name . "<br>";
$sam = new Employee("Sam");
echo $sam->name;
Определение псевдонимов можно сократить:
use \base\classes\{Person as User, Employee as Employee};
Подключение констант и функций вне класса
Для подключения констант внутри пространства имен применяется инструкция use const
, а для подключения функций внутри пространства имен - use function
.
Например, определение файла Person.php
:
<?
namespace base\classes;
const adminName = "Tom";
function printPerson($person) {
echo $person->name;
}
class Person {
public $name;
function __construct($name) {
$this->name = $name;
}
}
Подключим класс Person
вместе с константой adminName
и функцией printPerson
:
<?
namespace work;
include "Person.php";
use \base\classes\Person;
use const \base\classes\adminName;
use function \base\classes\printPerson;
$tom = new Person(adminName);
printPerson($tom); // Tom
Подключение функций внутри класса
Если нужно обратится к методу класса находящегося внутри пространства имен, есть два способа это сделать в зависимости от того статический метод или нет.
Вызов static метода объекта
::
подразумевает обращение к свойству/методу/константе класса в контексте класса (обычно статические свойства/методы и константы классов), не обязательно создавать объект можно обратиться так:
<?
namespace base\classes;
class Person {
public static function getName($name) {
echo $name;
}
}
Подключим класс Person
вместе с методом getName
:
<?
namespace work;
include "Person.php";
\base\classes\Person::getName("Tom");
Вызов public, protected, private, методов объекта
->
подразумевает обращение к свойству/методу класса в контексте объекта, обращение должно идти через объект:
<?
namespace base\classes;
class Person
{
public function getName($name)
{
echo $name;
}
}
Подключим класс Person
вместе с методом getName
:
<?
namespace work;
include "Person.php";
$o = new \base\classes\Person();
$o->getName("Tom");