Зачем указывать пространство имен при использовании автоматической загрузки psr-4 с помощью Composer?


Я немного смущен тем, как я должен использовать автоматическую загрузку psr-4 в Composer. Допустим, у меня такая структура папок:

/
|- Core/
|   - Router.php
|- App/
|   - Models
|       User.php
|- composer.json

В основном, в корне проекта: composer.json; Основная папка, содержащая Маршрутизатор класс php; Приложение папка, содержащая Модели папка, содержащая Пользователя класс.

Класс маршрутизатора выглядит следующим образом:

<?php
namespace Core;

class Router {
}

И класс пользователей выглядит так это:

<?php
namespace App\Models;

class User {
}

Таким образом, я могу автоматически загружать эти классы с помощью автозагрузчика Composer psr-4, я могу сделать это в composer.json:

{
    "autoload": {
        "psr-4": {
            "Core\\": "Core",
            "App\\Models\\": "App/Models"
        }
    }
}

Таким образом, я могу использовать классы, не требуя их (после запуска composer dump-autoload) следующим образом:

$router = new Core\Router();
$user = new App\Models\User();

Который работает без проблем.

Однако я также могу сделать это в composer.json:

{
    "autoload": {
        "psr-4": {
            "": ""
        }
    }
}

, который, согласно документации, является резервным каталогом, в котором может находиться любое пространство имен относительно корневого. Таким образом, имея эту "пустую" запись в загрузчик composer, в котором, как я полагаю, написано ", начиная с корневого каталога, ищите класс в любом пространстве имен", я могу автоматически загружать любой из своих классов, если буду следовать правильной структуре именования папок/пространства имен.

Итак, мой вопрос в том, зачем мне делать первое, если второе работает и намного проще? Это связано с производительностью? Или есть другая причина?

Author: Dave Hollingworth, 2016-03-22

3 answers

Почему бы тебе не делать это всегда "psr-4": {"": ""}?

Причина 1: Это снижает производительность. В определении говорится, что для КАЖДОГО класса, которому требуется автоматическая загрузка, Composer должен заглянуть в корневой каталог. Эти классы входят не только в ваш пакет, но и во все остальные классы.

Композитор пытается немного оптимизировать эти усилия, запоминая бесплодные поиски, но это окупается только в том случае, если вы загружаете другой класс с тем же префиксом.

Причина 2: Суть PSR-4 заключается в том, что вам не обязательно сопоставлять весь путь к пространству имен с путем к каталогу. Предполагая, что у вас есть пакет, который имеет дело с очень специфической группой классов, таких как \Vendor\Template\Escaping\Output\*, и ничего больше (наличие небольших пакетов облегчает их повторное использование без добавления слишком большого количества кода), вы можете иметь их в src/Vendor/Template/Escaping/Output/AnyClass.php и определить

"psr-4": {
        "\\Vendor\\Template\\Escaping\\Output\\": "src/Vendor/Template/Escaping/Output/"
}

Вы также можете поместить класс в src/AnyClass.php и определить

"psr-4": {
        "\\Vendor\\Template\\Escaping\\Output\\": "src/"
}

И это значительно сокращает путь к каталогу, незначительно повышая скорость (я думаю - хотя у меня нет цифр), но в основном улучшается разработка этой вещи за счет меньшего количества открываемых пустых папок.

Наличие пространства имен Core и пространства имен App в одном пакете вызывает у меня подозрения: почему для каждого из них нет одного пакета?

 6
Author: Sven, 2016-03-23 00:47:13

Обычно при использовании composer у вас есть только одна папка для вашего собственного проекта. Тогда вам нужно указать только одно пространство имен.

Подумайте, что вы изменили бы свою файловую структуру на

/
|- lib/
|   - Core/
|      - Router.php
|   - App/
|      - Models
|          User.php
|- composer.json

И измените свой файл composer.json на

{
    "autoload": {
        "psr-4": {
            "MyApp\\": "lib/"
        }
    }
}

Тогда у вас есть только одно указанное пространство имен, и вам не нужно добавлять какие-либо дополнительные пространства имен. Вы можете называть свои классы так:

$router = new \MyApp\Core\Router;
$user   = new \MyApp\App\Models\User;

Или вот так:

namespace MyApp;
$router = new Core\Router;
$user   = new App\Models\User;
 2
Author: Adam, 2017-06-17 06:43:15

PSR-4 - это стандарт, который преобразует пространства имен В физические каталоги.

 -4
Author: geggleto, 2016-03-22 16:50:40