Skip to content

Метадокумент PSR-4

1. Краткое содержание

Цель состоит в том, чтобы указать правила для интероперабельного автозагрузчика PHP, который сопоставляет пространства имен с путями файловой системы и может сосуществовать с любым другим SPL. зарегистрированный автозагрузчик. Это будет дополнением, а не заменой, ПСР-0.

2. Зачем беспокоиться?

История PSR-0

Стандарт именования и автозагрузки классов PSR-0 вырос из широкого принятие соглашения Horde/PEAR в условиях ограничений PHP 5.2 и предыдущий. При таком соглашении существовала тенденция помещать все исходные классы PHP в одном главном каталоге, используя символы подчеркивания в имени класса для обозначения псевдопространства имен, например:

/path/to/src/
    VendorFoo/
        Bar/
            Baz.php     # VendorFoo_Bar_Baz
    VendorDib/
        Zim/
            Gir.php     # Vendor_Dib_Zim_Gir

С выпуском PHP 5.3 и наличием собственных пространств имен PSR-0 был введен, чтобы разрешить как старый режим подчеркивания Horde/PEAR *, так и * использование новой нотации пространства имен. Подчеркивания по-прежнему разрешены в классе имя, чтобы упростить переход от старого именования пространства имен к новому именованию, и тем самым способствовать более широкому внедрению.

/path/to/src/
    VendorFoo/
        Bar/
            Baz.php     # VendorFoo_Bar_Baz
    VendorDib/
        Zim/
            Gir.php     # VendorDib_Zim_Gir
    Irk_Operation/
        Impending_Doom/
            V1.php
            V2.php      # Irk_Operation\Impending_Doom\V2

Эта структура во многом обусловлена тем фактом, что установщик PEAR переместился исходные файлы из пакетов PEAR в один центральный каталог.

А вот и composer

В Composer источники пакетов больше не копируются в один глобальный расположение. Они используются из места их установки и не перемещаются вокруг. Это означает, что в Composer нет «единого главного каталога» для Исходники PHP как с PEAR. Вместо этого есть несколько каталогов; каждый package находится в отдельном каталоге для каждого проекта.

Чтобы соответствовать требованиям PSR-0, это приводит к тому, что пакеты Composer выглядят так:

vendor/
    vendor_name/
        package_name/
            src/
                Vendor_Name/
                    Package_Name/
                        ClassName.php       # Vendor_Name\Package_Name\ClassName
            tests/
                Vendor_Name/
                    Package_Name/
                        ClassNameTest.php   # Vendor_Name\Package_Name\ClassNameTest

Каталоги «src» и «tests» должны включать имена каталогов поставщиков и пакетов. Это артефакт соответствия PSR-0.

Многие находят эту структуру более глубокой и более повторяющейся, чем необходимо. Это предложение предполагает, что дополнительный или заменяющий PSR был бы полезен, чтобы мы могли иметь пакеты, которые больше похожи на следующие:

vendor/
    vendor_name/
        package_name/
            src/
                ClassName.php       # Vendor_Name\Package_Name\ClassName
            tests/
                ClassNameTest.php   # Vendor_Name\Package_Name\ClassNameTest

Это потребовало бы реализации того, что первоначально называлось «автозагрузкой, ориентированной на пакеты» (в отличие от традиционной «автозагрузки напрямую из класса в файл»).

Пакетно-ориентированная автозагрузка

Сложно реализовать пакетно-ориентированную автозагрузку с помощью расширения или поправки к PSR-0, потому что PSR-0 не допускает промежуточного пути между любыми частями имени класса. Это означает, что реализация пакетно-ориентированного автозагрузчика будет сложнее, чем PSR-0. Тем не менее, это позволит использовать более чистые пакеты.

Первоначально были предложены следующие правила:

  1. Разработчики ДОЛЖНЫ использовать как минимум два уровня пространства имен: имя поставщика и имя пакета внутри этого поставщика. (Эта комбинация двух имен верхнего уровня далее называется именем пакета поставщика или пространством имен пакета поставщика.)

  2. Разработчики ДОЛЖНЫ разрешать инфикс пути между пространством имен пакета поставщика и остатком полного имени класса.

  3. Пространство имен vendor-package МОЖЕТ сопоставляться с любым каталогом. Оставшаяся часть полного имени класса ДОЛЖНА сопоставлять имена пространств имен с каталогами с одинаковыми именами и ДОЛЖНА сопоставлять имя класса с файлом с таким же именем, оканчивающимся на .php.

Обратите внимание, что это означает конец символа подчеркивания в качестве разделителя каталогов в имени класса. Кто-то может подумать, что символы подчеркивания должны соблюдаться, как и в PSR-0, но, учитывая, что их присутствие в этом документе относится к переходу от PHP 5.2 и предыдущего псевдопространства имен, их также можно удалить здесь.

3. Масштаб

3.1 Цели

  • Сохраните правило PSR-0, согласно которому разработчики ДОЛЖНЫ использовать как минимум два уровня пространства имен: имя поставщика и имя пакета внутри этого поставщика.

  • Разрешить инфикс пути между пространством имен пакета поставщика и оставшейся частью полного имени класса.

  • Разрешить пространство имен поставщика-пакета МОЖЕТ сопоставляться с любым каталогом, возможно, с несколькими каталогами.

  • Завершить использование знаков подчеркивания в именах классов в качестве разделителей каталогов.

3.2 Нецели

  • Предоставьте общий алгоритм преобразования для неклассовых ресурсов

4. Подходы

4.1 Выбранный подход

Этот подход сохраняет ключевые характеристики PSR-0, но устраняет необходимость в более глубоких структурах каталогов. Кроме того, он определяет некоторые дополнительные правила, которые явно делают реализации более совместимыми.

Хотя это и не связано с отображением каталогов, окончательный проект также указывает, как автозагрузчики должны обрабатывать ошибки. В частности, он запрещает создавать исключения или вызывать ошибки. Причина двоякая.

  1. Автозагрузчики в PHP специально спроектированы так, чтобы их можно было стекировать, поэтому, если один автозагрузчик не может загрузить класс, у другого есть шанс это сделать. Если автозагрузчик запускает критическое состояние ошибки, это нарушает эту совместимость.

  2. class_exists() и interface_exists() разрешают «не найдено даже после попытки автозагрузки» как законный, нормальный вариант использования. Автозагрузчик, выбрасывающий исключения, делает class_exists() непригодным для использования, что совершенно неприемлемо с точки зрения совместимости. Автозагрузчики, которые хотят предоставить дополнительную отладочную информацию в случае, если класс не найден, должны вместо этого делать это с помощью ведения журнала либо в совместимом с PSR-3 регистраторе, либо иным образом.

Плюсы:

  • Более мелкие структуры каталогов

  • Более гибкое расположение файлов

  • Предотвращает использование подчеркивания в имени класса в качестве разделителя каталогов.

  • Делает реализации более интероперабельными

Минусы:

  • Больше невозможно, как в PSR-0, просто проверить имя класса, чтобы определить, где оно находится в файловой системе (соглашение «класс-файл», унаследованное от Horde/PEAR).

4.2 Альтернатива: оставайтесь только с PSR-0

Оставаться только с PSR-0, хотя это и разумно, оставляет нас с относительно более глубокими структурами каталогов.

Плюсы:

  • Нет необходимости менять чьи-либо привычки или реализации

Минусы:

  • Оставляет нас с более глубокими структурами каталогов

  • Оставляет нас с символами подчеркивания в имени класса, которые считаются разделителями каталогов.

4.3 Альтернатива: разделить автозагрузку и трансформацию

Бо Сименсен и другие предположили, что алгоритм преобразования может быть отделен от предложения по автозагрузке, чтобы на правила преобразования можно было ссылаться в других предложениях. После выполнения работы по их разделению, последующего опроса и некоторого обсуждения, комбинированная версия (т. е. правила преобразования, встроенные в предложение автозагрузчика) была признана предпочтительной.

Плюсы:

  • На правила преобразования можно ссылаться отдельно в других предложениях.

Минусы:

  • Не соответствует пожеланиям респондентов опроса и некоторых сотрудников

4.4 Альтернатива: используйте более императивную и описательную речь

После того, как Спонсор отозвал второе голосование после того, как услышал от нескольких избирателей +1, что они поддержали идею, но не согласились (или не поняли) с формулировкой предложения, был период, в течение которого предложение, за которое проголосовали, было расширено за счет большего повествования и несколько более императивных формулировок. Этот подход был осужден громким меньшинством участников. Через некоторое время Бо Сименсен начал экспериментальную доработку с прицелом на PSR-0; Редактор и спонсоры поддержали этот более краткий подход и отдали предпочтение версии, которая сейчас находится на рассмотрении, написанной Полом М. Джонсом и подготовленной многими.

Примечание о совместимости с PHP 5.3.2 и ниже

Версии PHP до 5.3.3 не удаляют начальный разделитель пространств имен, поэтому ответственность за это ложится на реализацию. Если не удалить начальный разделитель пространства имен, это может привести к непредвиденному поведению.

5. Люди

5.1 Редактор

  • Пол М. Джонс, Солар/Аура

5.2 Спонсоры

  • Фил Стерджен, PyroCMS (координатор)
  • Ларри Гарфилд, Drupal

5.3 Участники

  • Андреас Хеннингс
  • Бернхард Шусек
  • Бо Сименсен
  • Дональд Гилберт
  • Майк ван Риэль
  • Пол Драгонис
  • Слишком много других, чтобы назвать и сосчитать

6. Голоса

7. Соответствующие ссылки