Может войдёшь?
Черновики Написать статью Профиль

Автозагрузка. Пространства имен. Composer.

TL;DR

Решение проблемы "сломанного пакета" или решение добавления автоподгрузки классов для пакета загруженного вручную смотри с пункта "Решение".

Вступление

К написанию данной статьи меня подтолкнула статья "Автозагрузка пространства имён в Laravel 5.3" (на данный момент уже удалена). В виду того что статья крайне вредная, по моему мнению. Далее постараюсь изложить материал точно и надеюсь понятно (во всяком случае часть с решениями).

Хьюстон, у нас проблема!

Но начать бы хотелось с очень забавного момента. Автор изначально неверно интерпретировал свою проблему и решение искал совершенно не того что ему было нужно. А именно он пишет:

Набираю команду composer require ИмяПакета

и читаю:

 [InvalidArgumentException]
  Could not find package ИмяПакета at any version for your minimum-stability (stable). Check the package spelling or your minimum-stability

Да, всё верно. Пакет приготовлен для старой версии Laravel. Но классы-то из старого пакета прекрасно работают.

Как из слов о "невозможности найти версию пакета, стабильность которой удовлетворяла бы стабильности, выставленной у проекта", автор сделал вывод о том, что он для старой версии Лары, я не знаю. Ему же даже совет composer дал. Посмотри, говорит, правильно ли указан пакет в команде, или свою настройку минимальной стабильности (minimum-stability).

Так вот, если бы мы правильно поняли именно ту проблему, то у нас было бы два пути решения.

Первый - это установить у себя в проекте в composer.json настройку "minimum-stability": "dev" (т.е. сменить со stable). Но этот вариант мне лично не очень нравится.

Второй вариант это при подключении пакета выставить вместе с версией специальный флаг @dev (stability flag). Т. е. нужно было выполнить команду composer require ИмяПакета @dev. Ну или если прописывать вручную, то указать этот флаг в секции версии при подключении пакета. Кстати в доке к тому пакету так и написано:

To get the latest version of SypexGeo simply require it in your composer.json file.

"scriptixru/sypexgeo": "0.2.*@dev"

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

Новичков прошу усвоить два урока:

  1. Внимательно читайте сообщения об ошибке.
  2. Учите инструменты которыми пользуетесь, читайте их документацию. (https://getcomposer.org/doc/)

О именах

Итак, улыбнувшись, и заодно, я надеюсь, поговорив о полезном, пойдем дальше. Отдельные страдания у меня вызывает заголовок той статьи - "Автозагрузка пространства имён в Laravel 5.3". То, что изложено в статье не имеет никакого отношения к Laravel и тем более к какой то определенной версии. А словосочетания "автозагрузка пространства имён" не существует. Автозагрузка есть у классов (интерфейсов, трейтов). Читаем тут - Автоматическая загрузка классов.

Ладно, и так сойдет

Ну а теперь если у нас всё же проблема с содержимым пакета (т.е. если бы действительно пакет имел прописанную зависимость на laravel 5.1, например) или если в пакете баг. Автор копирует пакет вручную, а потом правит внутренние файлы, используемые composer. И всё работает! Но, пожалуйста, не делайте так. Вообще, запомните простое правило "Ничего править внутри папки vendor нельзя".

  • Всё что там есть затирается при обновлении.
  • Вы не должны держать это под гитом, а следовательно при новой инсталляции (например, диплое) вам снова придется всё менять.

Но что же тогда делать?

Решение

Собственно решений проблемы описанной в той статье (т. е. что-то не так с вендорным пакетом) есть два.

"Упрощенное" решение

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

Его смысл - это вручную скопировать код пакета себе в проект и прописать автозагрузку. Только копировать проект стоит не в папку vendor а в свою произвольную папку, например, lib. И автозагрузку прописывать не меняя внутренние файлы composer'а, а добавив информацию в специальную секцию autoload конфигурации composer'а (т.е. файла composer.json). А что именно там прописать подскажет сам пакет. Заходим в его исходный код и смотрим в его composer.json - там так же есть секция autoload, вот её и повторяем, только добавив в начало пути, естественно, нашу часть, куда мы разместили пакет (т.е. например lib/ИмяПакета). И, вообще, желательно прочитать документацию по автозагрузке в php, о стандартах автозагрузки PSR-4 (PSR-0) и о автозагрузке в проектах с composer.

"True way"-решение

Вышеизложенный метод не совсем хорош, ибо мы потеряем возможность обновлять версию пакета, так же "замусорим" свой проект (репозиторий) чужим исходным кодом.

Лучше возьмите и сделайте форк кода пакета. Для этого вам понадобится аккаут на гитхабе и просто на github-странице пакета нажать кнопку Fork. Затем изменяем код так как нам нужно. Ну и далее нужно "сказать" композеру чтобы он искал пакет в уже нашем репозитории (т.е. использовал код из нашего форка). И для этого нам нужно добавить специальную секцию repositories в composer.json (подробнее читаем тут, а еще подробнее тут).

Нам же нужно будет написать следующее

    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/iam/pack.git"
        }
    ],

Конечно, там, где url, должен быть URL нашего форка. И при этом при подключении пакета надо выставить ему версию "dev-master".

И, конечно, же делаем pull request (запрос на изменение) в исходный проект, это как правило хорошего тона, и плюс, чтобы когда его примут, то мы могли бы убрать все наши "костыли" и просто использовать пакет.

Заключение

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

Как вы считаете, полезен ли этот материал? Да Нет

Комментарии (6)

Proger_XP

Да, вот это именно то, что нужно. Подробное описание со ссылками на доки.

ИМХО, вариант с изменением файлов Composer напрямую намного трудозатратней, чем собственно правильное решение — 90% пакетов уже и так на GitHub, у 90% разработчиков там тоже есть аккаунт, поэтому тыкнуть Fork и поменять URL в composer.json это дело двух минут. А через энное число дней, когда уже забыл про свои правки в vendor, не придётся биться головой об стену, пытаясь понять, с чего вдруг всё сломалось, и тратить время на поиски пакета, который внезапно «стал несовместимым».

p.s: очень много ошибок в пунктуации — я исправил, но не забывай про запятые, иначе сложно читать.

baboot

абсолютно, поддерживаю. Сам так делаю постоянно.

Ellrion

Спасибо за исправления. Да с грамматикой у меня всегда было плохо. Надо будет давать кому то вычитывать сначала, если буду еще писать.

Proger_XP

Автор исходной статьи «Автозагрузка пространства имён в Laravel 5.3» решил её выпилить, так что не ищите...

Ellrion

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

Proger_XP
  1. но и свою предыдущую, которую многие посчитали полезной.

Да, вот это определённо зря, первая статья действительно была многим очень полезна. В твоей статье ничего обидного нет, наоборот, всё объяснено и затрагивает частую проблему.

Написать комментарий

Разметка: ? ?

Авторизуйся, чтобы прокомментировать.