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"
Про это всё читать тут и тут. Если кратко, то мы там узнаем, какие бывают значения для указания уровня стабильности, и о том, что при подключении пакета можно использовать также флаги стабильности, позволяющие дополнительно ограничить или расширить стабильность пакета отлично от установки минимальной стабильности.
Новичков прошу усвоить два урока:
- Внимательно читайте сообщения об ошибке.
- Учите инструменты которыми пользуетесь, читайте их документацию. (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)
Да, вот это именно то, что нужно. Подробное описание со ссылками на доки.
ИМХО, вариант с изменением файлов Composer напрямую намного трудозатратней, чем собственно правильное решение — 90% пакетов уже и так на GitHub, у 90% разработчиков там тоже есть аккаунт, поэтому тыкнуть Fork и поменять URL в composer.json это дело двух минут. А через энное число дней, когда уже забыл про свои правки в vendor, не придётся биться головой об стену, пытаясь понять, с чего вдруг всё сломалось, и тратить время на поиски пакета, который внезапно «стал несовместимым».
p.s: очень много ошибок в пунктуации — я исправил, но не забывай про запятые, иначе сложно читать.
абсолютно, поддерживаю. Сам так делаю постоянно.
Спасибо за исправления. Да с грамматикой у меня всегда было плохо. Надо будет давать кому то вычитывать сначала, если буду еще писать.
Автор исходной статьи «Автозагрузка пространства имён в Laravel 5.3» решил её выпилить, так что не ищите...
Видимо я его всё же обидел, так как он удалил не только ту статью, но и свою предыдущую, которую многие посчитали полезной. А жаль, такой цели у меня не было.
Да, вот это определённо зря, первая статья действительно была многим очень полезна. В твоей статье ничего обидного нет, наоборот, всё объяснено и затрагивает частую проблему.