Чтобы понять как работают пространства имен мы начнем с того, что создаем и вызываем классы в глобальном пространстве имен:
// file_1.php
class UserClass{
public function __construct(){
echo "Это UserClass";
}
}
// file_2.php
require_once("file_1.php");
$uc = new UserClass();
Все работает, при выполнении кода выводится сообщение "Это UserClass".
Теперь добавим лишь одну строчку с указанием некоего пространства имен:
// file_1.php
namespace MyClassNamespace;
class UserClass{
public function __construct(){
echo "Это UserClass";
}
}
Теперь при вызове file_2.php получаем ошибку:
Fatal error: Uncaught Error: Class 'UserClass' not found in ...file_2.php
Причина, по которой мы получаем ошибку заключается в том, что в глобальнм пространстве имен уже нет класса UserClass.
Стоит отметить! Объявляя пространство имен в файле file_1.php мы обозначаем, что указанные ниже по коду классы, константы (указанные через ключевое слово const) и функции будут доступны только в этом пространстве имен. Обычные переменные типа $var и константы, определенные через define() будут доступны глобально.
Чтобы обратиться к классу (или константе) нужно указать пространство имен, в котором он находится. Мы разберем несколько вариантов того, как это можно сделать.
Вариант 1: Указать пространсво имен непосредственно при вызове класса
// file_2.php
require_once("file_1.php");
$uc = new MyClassNamespace\UserClass();
Вариант 2: использовать оператор use для определения пространства имен для используемого класса
// file_2.php
require_once("file_1.php");
use MyClassNamespace\UserClass;
$uc = new UserClass();
Вариант 2.1: Добавить псевданим с возможностью указать произвольное имя
// file_2.php
require_once("file_1.php");
use MyClassNamespace\UserClass as CurrentUser;
$uc = new CurrentUser();
Как обратиться к глобальному классу изнутри некоего пространства имен
Причина такого вопроса в том, что обозначая свое пространство имен мы перестаем иметь непосредственный контакт с глобальным пространством имен.
Для обращения к классу, функции или константе нам нужно указать обратный слэш перед их именем: \GlobalUserClass()
// file_3.php
class GlobalUserClass{
public function __construct(){
echo "Это GlobalUserClass\r\n";
}
}
// file_4.php
namespace MyNamespace; // Обозначаем пространство имен
// Подключаем класс с глобальным пространство имен
require_once("file_3.php");
$guc1 = new \GlobalUserClass();
Благодаря вызову с обратным слэшом мы получили доступ к классы, находящемуся в глобальном пространстве имен
Вложенные зоны видимостимости. Есть ли такое?
Часто можно увидеть запись на подобии App\Category\Utilits\Awesome. Как стоит интерпретировать такую последовательность?
В PHP, в отличии от Python или Java, по историческим причинам нет строгой зависимости между пространствами имен и файловой структурой. Однако, следуя стандартам качества кода, разработчики следят за тем, чтобы пространства имен точно соответствовали названиям папок в файловой системе. Поэтому, такая вложенность означает, что исполняемый класс Awesome наверняка будет находиться в файле Awesome.php, который находится в папке App\Category\Utilits. Или (реже) — в папке App\Category будет найден файл Utilits.php, в котором расположен класс Awesome(). Но где находится папка App и называется ли она именно так — на этот вопрос сложнее ответить. Но чаще всего это какой-то интуитивно понятный корневой раздел проекта. Также подсказку можно найти в файле composer.json — там может быть указан алиас для корневого каталога.
Например в Laravel 6 (в тестовом проекте blog) мы можем увидеть строчку:
use Illuminate\Foundation\Auth\User as Authenticatable;
Это будет означать, что нужно заглануть в файл vendor\laravel\framework\src\Illuminate\Foundation\Auth\User.php
На этом все!
Пишите в комментариях нашли ли вы в этой заметки все ответы на свои вопросы по данной теме.
Комментарии (3)
Не писать ответ