Пространства имён в PHP: как сделать правильно с первого раза
Разбираем, как объявить namespace, подключить классы через use и связать всё с автозагрузкой PSR-4, чтобы не ловить Class not found. Для PHP 8.x.

К концу этой инструкции у вас будет проект, где классы лежат в папках по логике, подключаются одной строкой use, а автозагрузчик Composer сам находит нужный файл — без единого require вручную. На чистую настройку уйдёт минут пятнадцать. Разбор написан для PHP 8.1+ и Composer 2.x; в более старых версиях синтаксис пространств имён тот же, но за автозагрузку отвечали другие механизмы.
Что нужно иметь до начала
- PHP 8.1 или новее. Проверьте:
php -vдолжно вывести версию 8.1.x или выше. - Composer 2.x, установленный глобально. Проверьте:
composer --version. - Пустая папка под проект и права на запись в ней.
- Любой редактор кода. IDE вроде PhpStorm подсказывает импорты, но для инструкции хватит и обычного.
Если php -v выдаёт ошибку «command not found», интерпретатор не в PATH — это отдельная тема, здесь считаем, что PHP и Composer уже работают из терминала.
Зачем вообще пространства имён
Пространство имён1 — это префикс, который отделяет ваши классы от чужих. Без него два класса Logger из разных библиотек столкнутся, и PHP выбросит Cannot declare class Logger, because the name is already in use. С namespace один станет App\Logger, другой — Monolog\Logger, и конфликт исчезает.
Пространство имён — это не про папки на диске. Это логическое имя. То, что оно обычно совпадает с путём к файлу, — договорённость PSR-4, а не требование языка. Но нарушать её не стоит: на ней держится автозагрузка.
Шаг 1. Инициализируем Composer и задаём корень namespace
В папке проекта выполните:
composer init
Composer задаст вопросы — имя пакета, описание, зависимости. На вопросах про зависимости отвечайте no. В результате появится файл composer.json. Откройте его и добавьте секцию autoload:
{
"name": "me/my-project",
"require": {
"php": ">=8.1"
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
Строка "App\\": "src/" означает: всё, что начинается с namespace App\, ищи в папке src/. Двойной обратный слэш — это экранирование внутри JSON, реальный префикс один: App\.
Проверка: файл composer.json сохранён, секция autoload на месте.
Шаг 2. Создаём класс в пространстве имён
Создайте папку src, а в ней файл Logger.php:
<?php
namespace App;
class Logger
{
public function write(string $message): void
{
// Пишем строку с меткой времени в стандартный вывод
echo date('H:i:s') . ' ' . $message . PHP_EOL;
}
}
Строка namespace App; должна быть первой инструкцией в файле — до неё допустимы только тег <?php и объявление declare. Ни одного пробела или вывода перед <?php: лишний символ ломает и заголовки, и автозагрузку.
Обратите внимание: имя файла (Logger.php) совпадает с именем класса (Logger), а папка src/ соответствует префиксу App\. Это и есть правило PSR-4 в действии.
Проверка: путь к файлу — src/Logger.php, класс называется Logger, namespace — App.
Шаг 3. Обновляем автозагрузчик
Composer генерирует карту автозагрузки. После изменения секции autoload или добавления первых классов выполните:
composer dump-autoload
Команда создаст (или обновит) папку vendor с файлом vendor/autoload.php. Именно его вы будете подключать вместо ручных require.
Проверка: появилась папка vendor, внутри есть autoload.php. В терминале — строка вроде Generated autoload files.
Шаг 4. Используем класс через use
В корне проекта создайте файл index.php:
<?php
require __DIR__ . '/vendor/autoload.php';
use App\Logger;
$logger = new Logger();
$logger->write('Пространства имён работают');
Строка use App\Logger; импортирует полное имя класса, чтобы дальше писать короткое Logger. Без use пришлось бы каждый раз указывать new \App\Logger() — ведущий обратный слэш означает «отсчёт от корня», а не от текущего namespace.
Запустите:
php index.php
Проверка: в терминале появится строка с текущим временем и текстом «Пространства имён работают». Если она появилась — автозагрузка и импорт настроены верно.
Вложенные пространства имён
Когда классов станет больше, раскладывайте их по подпапкам. Файл src/Service/Mailer.php получит namespace App\Service:
<?php
namespace App\Service;
class Mailer
{
public function send(string $to): void
{
echo 'Письмо для ' . $to . PHP_EOL;
}
}
Подключается так же — use App\Service\Mailer;. Каждый уровень namespace = один уровень папки. Нарушите соответствие — Composer не найдёт файл, и вы получите Class "App\Service\Mailer" not found.
Псевдонимы: когда классы называются одинаково
Если в одном файле нужны два Logger из разных мест, дайте одному псевдоним через as:
use App\Logger;
use Monolog\Logger as MonologLogger;
$my = new Logger();
$external = new MonologLogger('channel');
Псевдоним живёт только в этом файле и не меняет реальное имя класса.
Если не получилось
Пять ошибок, которые вы реально увидите, и что с ними делать:
Uncaught Error: Class "App\Logger" not found— не совпадает регистр или путь. Проверьте: папка ровноsrc, файлLogger.phpс заглавной L, namespaceAppбез опечаток. PSR-4 чувствителен к регистру на Linux-серверах, даже если на Windows «работало».- Изменения не подхватываются — забыли
composer dump-autoloadпосле добавления класса или правкиcomposer.json. Composer кеширует карту классов. Fatal error: Namespace declaration statement has to be the first statement— передnamespaceесть код, пробел или пустая строка после<?php. Уберите всё лишнее.Failed to open stream: No such file or directoryнаvendor/autoload.php— не выполнилиcomposer installилиcomposer dump-autoload, папкиvendorещё нет.- Класс из подпапки не находится, а из корня — да — namespace в файле не отражает вложенность. Файл в
src/Service/обязан иметьnamespace App\Service;, а неnamespace App;.
Частая путаница: use и require — это разное
| Инструкция | Что делает | Когда нужна |
|---|---|---|
require 'vendor/autoload.php' | Подключает файл автозагрузчика один раз в точке входа | В index.php или бутстрапе проекта |
use App\Logger; | Импортирует имя класса, чтобы писать коротко | В начале каждого файла, где нужен класс |
namespace App; | Объявляет, какому пространству принадлежит код файла | Первой строкой в файле с классом |
Новички часто думают, что use подключает файл. Нет — файл находит автозагрузчик, а use лишь сокращает запись имени.
Что делать дальше
Настройте отдельный namespace для тестов — например App\Tests\ с папкой tests/ в секции autoload-dev файла composer.json, чтобы тестовый код не попадал в продакшен-автозагрузку. Когда добавите первую внешнюю библиотеку через composer require, её namespace тоже станет доступен автоматически — трогать свою секцию autoload не придётся. Точный синтаксис секций сверяйте с документацией Composer по schema.
Репетитор 1—11 класс и ВУЗ: Математика и физика методом наведения на мысль, помощь с ДЗ.
Спросить за 8 ₽Источники: PHP Manual: Namespaces, Composer: autoload schema
Частые вопросы
У меня PHP 7.4, всё это сработает?
Класс не находится, хотя путь вроде правильный. Что смотреть первым?
Обязательно ли использовать Composer для пространств имён?
Можно ли назвать корневой namespace не App, а как-то иначе?
Нужно ли писать use для классов из того же namespace?
Что делать с функциями и константами — им тоже нужен namespace?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.