Что такое namespace в PHP?

Ответ

Пространства имён (namespaces) в PHP — это механизм для инкапсуляции и организации элементов кода (классов, интерфейсов, функций и констант), предназначенный для решения двух основных проблем:

  1. Избежание конфликтов имён между кодом вашего приложения, внутренними классами PHP и сторонними библиотеками.
  2. Создание псевдонимов (алиасов) для длинных имён, что улучшает читаемость кода.

Без namespace класс Logger из вашей библиотеки мог бы конфликтовать с классом Logger из фреймворка. С namespace они становятся MyVendorMyAppLogger и FrameworkLoggingLogger.

Объявление и использование:

// Файл: src/MyVendor/MyApp/Logger.php
namespace MyVendorMyApp; // Объявление пространства имён

class Logger {
    public function log($message) {
        echo "[" . date('Y-m-d H:i:s') . "] $messagen";
    }
}

// Файл: src/MyVendor/MyApp/Utils/Helper.php
namespace MyVendorMyAppUtils; // Вложенное пространство имён

function debug($data) {
    var_dump($data);
}

Использование в другом файле:

// index.php

// 1. Использование полного имени (fully qualified name)
$logger1 = new MyVendorMyAppLogger();
$logger1->log("Starting app...");

// 2. Использование оператора `use` для создания алиаса
use MyVendorMyAppLogger;
$logger2 = new Logger();
$logger2->log("Another log");

// 3. Использование `use` с псевдонимом (alias) при конфликте имён
use MyVendorMyAppLogger as AppLogger;
use FrameworkLoggingLogger as FrameworkLogger;

$appLog = new AppLogger();
$fwLog = new FrameworkLogger();

// 4. Импорт функции из namespace (требует PHP 5.6+)
use function MyVendorMyAppUtilsdebug;
debug([1, 2, 3]);

Глобальное пространство имён: Классы и функции, объявленные без namespace, или с обратным слэшем в начале, находятся в глобальном пространстве.

// Обращение к встроенному классу PHP из пространства имён
$dt = new DateTime(); // Явное указание глобального пространства

// Или после импорта
use DateTime;
$dt = new DateTime();

Пространства имён — обязательный инструмент для структурирования кода в современных PHP-проектах и при работе с Composer (PSR-4 autoloading).

Ответ 18+ 🔞

Слушай, а давай про эти ваши namespace в PHP поговорим, а? Просто чтобы ты понимал, зачем эта вся движуха нужна, а не просто так, потому что в Laravel так делают.

Представь себе, блядь, ёперный театр. У тебя в проекте есть класс Logger. И тут ты подключаешь какую-нибудь библиотеку от левых чуваков, а у них там тоже класс Logger. И твой PHP такой: «Э, сабака сука! Какой из двух Logger-то мне создать?» И всё, приехали — конфликт имён, ошибка фатальная, проект накрылся медным тазом. Вот чтобы такого пиздеца не было, и придумали пространства имён. Это как папки на компе: у тебя может быть C:работаотчетынакладная.xlsx и C:личноеразводнакладная.xlsx. Файлы-то оба накладная.xlsx, но пути разные — и конфликта нет. Вот и тут так же.

Без namespace — пизда рулю. С namespace — красота. Твой логгер будет МояКомпанияМойПроектLogger, а логгер из фреймворка — FrameworkLoggingLogger. Всё, приехали, проблем больше нет.

Как это объявляется, ёпта:

// Файл: src/MyVendor/MyApp/Logger.php
namespace MyVendorMyApp; // Всё, объявили. Теперь всё внутри — в этой вот «папке».

class Logger {
    public function log($message) {
        echo "[" . date('Y-m-d H:i:s') . "] $messagen";
    }
}

А можно и вложенную «папку» сделать, для порядка:

// Файл: src/MyVendor/MyApp/Utils/Helper.php
namespace MyVendorMyAppUtils; // Типа залез в подпапку Utils

function debug($data) {
    var_dump($data);
}

А теперь, чувак, как этим пользоваться в другом месте:

Есть несколько способов, выбирай какой удобнее.

  1. Прямо в лоб, полным именем. Как паспорт предъявить.

    $logger1 = new MyVendorMyAppLogger(); // Всё, явно указал, откуда брать.
    $logger1->log("Запускаюсь...");

    Работает, но писать каждый раз MyVendorMyApp — это, блядь, терпения ноль ебать. Особенно если имя длинное.

  2. Импорт через use. Самый частый способ. Сказал один раз в начале файла «используй вот этот класс», и потом просто по имени обращаешься.

    use MyVendorMyAppLogger; // Импортировали
    $logger2 = new Logger(); // И теперь просто `new Logger()`. Удобно, ёба!
    $logger2->log("Ещё одна запись");
  3. Импорт с псевдонимом (алиасом), когда имена конфликтуют. Вот тут магия. Допустим, у тебя ДВА логгера из разных мест. Без паники!

    use MyVendorMyAppLogger as AppLogger; // Этот будет AppLogger
    use FrameworkLoggingLogger as FrameworkLogger; // А этот FrameworkLogger
    
    $appLog = new AppLogger();
    $fwLog = new FrameworkLogger();

    Всё, конфликт решён, можно спать спокойно. Доверия ебать ноль к тем, кто этого не использует.

  4. Импорт функций и констант. Да, и их тоже можно!

    use function MyVendorMyAppUtilsdebug; // Импортируем функцию (PHP 5.6+)
    debug([1, 2, 3]); // И юзаем её

Отдельная тема — глобальное пространство.

Всё, что объявлено без namespace (как старые классы) или с обратным слешем в начале, живёт в корне, в глобальной зоне. Например, встроенные в PHP классы вроде DateTime. Если ты внутри своего namespace, и тебе нужен такой глобальный класс, надо явно на него указать:

namespace MyVendorMyApp;

$dt = new DateTime(); // Вот так, со слешем вначале. Говорим PHP: «Ищи в корне, а не у меня тут».
// Или импортируй через use, как нормальный человек:
use DateTime;
$dt = new DateTime();

Короче, подозрение ебать чувствую к любому современному проекту без namespace. Это ж основа основ, без этого ни Composer с его PSR-4 автозагрузкой нормально не работает, ни какие библиотеки подключать. Так что учи, это не просто прихоть, а реально нужная штука, чтобы не охуеть от бардака в коде.