RayMefise
@RayMefise
Java, PHP, C, C++, C#, .NET, QT

PSR-0 или PSR-4, и как правильно построить структуру проекта?

Всем привет. Недавно познакомился со стандартами написания кода и если честно немного запутался в их описании.

Первый вопрос который меня интересует это PSR-0 или PSR-4. На сколько я понял по состоянию на 21 октября 2014 года PSR-0 был помечен как устаревший. В настоящее время рекомендуется использовать PSR-4 в качестве замены, но PSR-1 и PSR-2 ссылаются на PSR-0, а про PSR-3 я вообще как-то не нашел русскоязычной информации, словно такого стандарта нет.

Второй вопрос связан с иерархией по стандарту PSR-0 или PSR-4.

В примерах приводят следующее:
\Doctrine\Common\IsolatedClassLoader => /path/to/project/lib/vendor/Doctrine/Common/IsolatedClassLoader.php

\Symfony\Core\Request => /path/to/project/lib/vendor/Symfony/Core/Request.php

\Zend\Acl => /path/to/project/lib/vendor/Zend/Acl.php

\Zend\Mail\Message => /path/to/project/lib/vendor/Zend/Mail/Message.php


насколько я понимаю
/path/to/project/ это путь к проекту и данный путь нигде не фигурирует, это та директория из которой запускается основной index.php
./lib/ это папка в которой я должен хранить свои библиотеки
./vendor/ это папка назначение которой я не понимаю, так как поставщик насколько я понимаю идет дальше
в итоге насколько я понял путь строится так
<путь к проекту>/lib/vendor/<Наименование производителя>/(<Пространство имен>/)<Название класса>.php

это соответствует пространству имен
<Наименование производителя>\(<Пространство имен>\)<Название класса>


но в других примерах я встречал следующее:
вместо "lib" используют "src" а каталога vendor попросту нет.
или подобного рода структуру
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, когда lib, когда tests, почему в некоторых структурах приходится дважды указывать имя поставщика и имя пкета и т.д.

Скорее всего тут все очень просто, но у меня почему-то вызывает диссонанс в примерах с разных источников.

На всякий случай приведу пример иерархии своей CMS системы которую я разрабатываю:
./ROOT/ - ядро системы
./ROOT/classes/ - системные классы для работы ядра системы и дающие доступ к ядру из сторонних пакетов
./ROOT/configure/ - тут хранится все что связано с настройкой cms системы
./ROOT/kernel/ - тут лежат файлы самого ядра
./localization/ - тут лежат файлы локализации для системы и ее компонент и модулей. У них своя внутренняя иерархия.
./resources/ - тут лежат файлы ресурсов для работы компонент и модулей, а также все что получает cms система из вне или создает по средством работы самой системы, попадает сюда. Внутри каталога своя строгая иерархия.
./templates/ - тут лежат файлы с шаблонами страниц. к каждой странице сайта привязан один из этих шаблонов.
./components/ -компоненты. 
./components/<имя компоненты>/ - По сути это программа которая имеет выходной класс обязательно унаследованный от системного. Обеспечивает подключение к странице основного контента. Грубо говоря это то что отображается в зоне контента на странице. Может быть настроен для разных страниц по своему. Имеет закрепленный за ним набор обязательных и необязательных параметров и позволяет выбирать шаблон для отображения. Обязателен для страницы и может быть только один на странице.
./modules/ - модули
./modules/<имя модуля>/ - по сути схож с компонентами, за исключением того что располагается в определенных блоках шаблона для каждой страницы.
./plugins/ - плагины
./plugins/<имя плагина>/ - по сути это код который в явном виде не используется в системе, но добавляет ей дополнительные возможности, как например плагин который подключает на странице нужную библиотеку jqwery
./utilities/ - тут лежат утилиты для работы с системой, например утилита обновления, миграции данных, проверки на ошибки и т.д.
./lib/ - тут лежат библиотеки которые используются в модулях, компонентах и плагинах.
./lib/<имя поставщика>/<пространство имен>/<имя файла>.php (соответствует пространству имен <имя поставщика>\<пространство имен>\<имя файла>)
./index.php - основной файл который запускается при обращении к сайту. Он является обработчиком запросов, запускает ядро и возвращает результат.
  • Вопрос задан
  • 17417 просмотров
Решения вопроса 2
27cm
@27cm
TODO: Написать статус
Первый вопрос который меня интересует это PSR-0 или PSR-4. На сколько я понял по состоянию на 21 октября 2014 года PSR-0 был помечен как устаревший.

PSR-4 не замена PSR-0, а дополнением к нему.
github.com/php-fig/fig-standards/blob/master/accep...


про PSR-3 я вообще как-то не нашел русскоязычной информации, словно такого стандарта нет

Видать, не перевели. Читайте в оригинале:
github.com/php-fig/fig-standards/blob/master/accep...


/path/to/project/ это путь к проекту и данный путь нигде не фигурирует, это та директория из которой запускается основной index.php

Да, это пусть к PHP файлам проекта. Но index.php обычно выносят в отдельный каталог (например, /public), а все классы проекта хранятся, например, в /src (или /lib или ещё как угодно). В конфигурации веб-сервера запрещают отправлять запросы к любым файлам, не лежащим в /public, благодаря этому /public/index.php является единственной точкой входа для внешних запросов.


./vendor это папка назначение которой я не понимаю

Это папка для сторонних библиотек, используемых в вашем проекте. Используется composer'ом. Внутрь лезть особо причин нет, composer сам решит как ему там всё разложить. Свои классы вы туда тоже не должны писать.


в итоге честно говоря я запутался в том как правильно надо строить свои каталоги, какие папки обязательные какие нет, когда использовать src, когда lib, когда tests, почему в некоторых структурах приходится дважды указывать имя поставщика и имя пкета и т.д.

src и lib - скажем так, синонимы. Кому как больше нравится. Главное, что внутри лежат сами PHP файлы проекта, следующие стандарту PSR-4. Лежат там только файлы, написанные авторами проекта. Поэтому нет смысла класть vendor внутрь src (или lib).
test - каталог для тестов проекта.
В папке vendor имя поставщика и имя проекта могут совпадать, вот они и дублируются.

Так как вы изобретаете свой велосипед, то и структуру каталогов делайте свою, или посмотрите на популярные CMS/фреймворки, но везде будет по-разному. Joomla, WordPress, Yii, Zend Framework, Symfony.

Я придерживаюсь такой структуры:
/config                     Глобальные настройки проекта.
/data                       Временные файлы. Например:
/data/cache	            Файлы кеша.
/data/logs	            Логи.
/data/tmp	            Прочие временные файлы.
/module                     Модули проекта. Например:
/module/Backend	        
/module/Backend/config      Настройки модуля.
/module/Backend/src	    Файлы PHP модуля. Например:
/module/Backend/src/Backend/Path/To/ExampleClass.php
/module/Backend/test	    Unit-тесты модуля.
/module/Backend/view	    Шаблоны модуля.
/module/Frontend/...
/public/index.php
/public/css
/public/font
/public/img
/public/js
/vendor


Возможно, я ошибаюсь, но самая главная ваша беда в том, что вы решили разрабатывать собственную CMS, не поработав с существующими, не выявив достоинства и недостатки их архитектур и структур каталогов.
Ответ написан
delphinpro
@delphinpro Куратор тега PHP
frontend developer
/path/to/project/ это путь к проекту и данный путь нигде не фигурирует, это та директория из которой запускается основной index.php

Нет. Этот корневая директория проекта. Из нее запускается композер. В ней же обычно лежит DOCUMENT_ROOT каталог, в котором уже и находится точка входа index.php. Также здесь лежат директории vendor (для сторонних пакетов) какой нибудь application/ для ваших файлов.

Давайте попробую объяснить на примере.

Пусть будет такая структура, например.

60926735302a7422195552.png

в vendor - вам ничего самому писать не нужно. Этот папка для композера.
public_html - в ней только index.php и все ваши css, images, js. Это папка на которую указывает DOCUMENT__ROOT в настройках домена вашего сервера. Только эти файлы доступны "по интернету".
application - здесь все ваши самописные php файлы.
(На остальные каталоги не обращаем внимания, в корне проекта можно располагать все что вам удобно, это не будет доступно из web)

Под такую структуру написан подобный composer.sjon
{
  "require": {
    "php": ">=5.5.9",
    "slim/slim": "2.*",
    "twig/twig": "~1.18",
    "slim/views": "^0.1.3",
    "robmorgan/phinx": "^0.4.4",
    "illuminate/database": "^5.1"
  },
  "minimum-stability": "stable",
  "autoload": {
    "psr-4": {
      "MyName\\MyProject\\": "application"
    }
  }
}

Тут вроде бы все просто. В require перечислены используемые пакеты. Поясню только autoload. Автозагрузка по стандарту PSR-4. Указано пространство имен ваших файлов и папка в которой они лежат.
Если ваш класс MyClass лежит в папке application - то у него должно быть пространство имен \MyName\MyProject (полное имя класса получается \MyName\MyProject\MyClass). Если ваш класс MyController лежит в папке application/Mvc/Controllers, то, соответственно \MyName\MyProject\Mvc\Controllers\MyController.

При этом вам не нужно заморачиваться и писать автозагрузчик. Просто выполните команду php composer.phar install (или php composer.phar dumpautoload для пересборки аавтозагрузчика) и подключите файл автозагрузчика в index.php
include '../vendor/autoload.php';

Не использовать композер не имеет смысла, т.к. это очень просто. Просто скачайте файл https://getcomposer.org/composer.phar в корень проекта и пользуйтесь (см выше).
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы