Чтобы понять как работают пространства имен мы начнем с того, что создаем и вызываем классы в глобальном пространстве имен:
// 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)
Не писать ответ