Рассказ об использовании Composer в плагине WordPress

Опубликовано: 2015-07-06

петерзум Эта часть была предоставлена ​​приглашенным автором Питером Сумом. Питер — веб-разработчик из страны датчан. Он создатель WP Pusher и большой любитель путешествий, который приносит с собой свою работу.


На днях я опубликовал предупреждение об использовании Composer в плагинах WordPress в блоге WP Pusher. Этот пост привлек много внимания, и я чувствую необходимость прояснить несколько моментов, которые не всем были понятны. Статья также была немного перегружена техническими вещами, поэтому в этом посте я попытаюсь сделать свою основную мысль более ясной, используя простое повествование для ее иллюстрации.

Повествование

фото предоставлено: Doors Open Toronto 2008 - Архивы Торонто - (лицензия)
фото предоставлено: Doors Open Toronto 2008 – Архивы Торонто – (лицензия)

Давайте на время представим, что мы с вами являемся авторами плагинов. У нас обоих есть отличная идея для плагина, который мы хотим распространять через WordPress.org. Мы хотим включить в наши плагины несколько премиальных функций, которые пользователи бесплатной версии смогут разблокировать, введя лицензионный ключ.

Нам нужен код, который может обрабатывать этот процесс. Мы оба понимаем, что эту проблему, вероятно, уже решил кто-то другой. Никто из нас не любит изобретать велосипед, поэтому мы идем на Packagist и вводим «менеджер лицензий». Похоже, наше предположение оправдалось. У Yoast уже есть пакет, который может справиться с этим. Мы оба решили сделать быстрый composer require yoast/license-manager . Очень просто. Теперь мы можем перейти к работе над чем-то действительно важным — основными функциями наших соответствующих плагинов.

Перенесемся вперед, готовясь выпустить свой плагин, вы понимаете кое-что: у вашего пользователя не обязательно должен быть под рукой Composer при установке вашего плагина с WordPress.org, так как же они собираются получить код для менеджера лицензий? Эта ситуация немного раздражает, потому что единственное решение, которое вы действительно видите, — это просто передать весь сгенерированный Composer каталог vendor в ваш плагин и отправить его на WordPress.org. Вы знаете, что это не то, как должен работать Composer, но что угодно. У вас действительно нет других вариантов.

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

Еще раз перемотаем вперед: оба наших плагина теперь находятся в репозитории WordPress.org, и время от времени кто-то решает перейти на наши премиум-версии. Кажется, все в порядке, и мы оба благодарны за то, что можем просто использовать код, исходный код которого щедро предоставил Yoast, и нам не пришлось изобретать велосипед.

Однажды вы получаете странное электронное письмо. Клиент испытывает действительно странное поведение при попытке разблокировать ваши премиум-функции. Для вас это не имеет смысла, потому что больше никто об этом не сообщал. После нескольких часов отладки вы, наконец, просите своего клиента деактивировать все остальное, кроме вашего плагина, и тогда: Это работает! Хм. Похоже, ваш плагин каким-то образом несовместим с другим плагином. Мой плагин.

Вы понимаете это после нескольких часов просмотра исходного кода всех других плагинов, установленных клиентом. Когда вы понимаете, что мы оба используем менеджер лицензий, звенит звонок. Может ли это быть на самом деле? Если да, то почему нет fatal errors: cannot redeclare class , вызванный PHP?

Неделей ранее я поднял требуемую версию менеджера лицензий в своем плагине до последней версии, которая включала некоторые (вымышленные) критические изменения. После еще большей отладки и var_dump() вы понимаете, что моя версия менеджера лицензий также является версией, загруженной PHP в ваш плагин. Вы находите это действительно странным, потому что вам специально требовалась другая версия менеджера лицензий с Composer. Вы действительно не знаете, что с этим делать.

Потому что на самом деле вы мало что можете с этим поделать.

Что здесь случилось?

Теперь, когда мы все увидели проблему, давайте рассмотрим, что на самом деле произошло в повествовании. Прежде всего, почему PHP не вызвал фатальную ошибку, когда два класса явно имели одно и то же имя, которое мы оба включили в менеджер лицензий?

Причина этого в том, что мы использовали автозагрузчик, сгенерированный Composer. Этот автозагрузчик сканирует структуру каталогов наших зависимостей и добавляет каждый класс в автозагрузчик. Если класс уже добавлен, Composer проигнорирует его. Тихо. Я написал небольшой пример кода, если вы хотите увидеть его сами. Это на GitHub.

Почему моя версия менеджера лицензий была включена раньше вашей?

Это произошло потому, что у моего плагина было имя, из-за которого он загружался раньше вашего. Может быть, в будущем мы все будем называть наши плагины «Аааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааа»

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

Это конкретная проблема Composer?

Нет. Это действительно не так. WordPress не имеет возможности работать со сторонним кодом в плагинах или темах. В этом и проблема. Причина, по которой я говорю о Composer, заключается в том, что в наши дни он набирает обороты. Если разработчики WordPress хотят использовать Composer в плагинах, выпущенных через WordPress.org, это нужно как-то решить. В противном случае мы увидим настоящий хаос, когда все плагины начнут несовместимы друг с другом, потому что используют разные версии. Добро пожаловать в ад отладки.

Что мы можем с этим сделать?

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

Многие разработчики уже включают сторонний код в свои плагины. Это действительно проблема?

Да, это уже проблема в экосистеме плагинов. Будет еще хуже, когда все больше людей поймут, что лучше всего размещать общие функции в отдельных пакетах. Затем эти пакеты могут быть объединены с несколькими плагинами, и проблема будет появляться все больше и больше. Я разговаривал с парой разработчиков, которые уже прошли через ад отладки, пытаясь выяснить, что вызывает эту проблему.

Двигаясь вперед, не могли бы вы предложить разработчикам прекратить включать сторонний код в свои плагины?

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

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

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

Что могут сделать разработчики плагинов, чтобы предотвратить эту проблему?

Существует обходной путь, который, как я видел, уже используют некоторые люди. В основном это сводится к перемещению вашей зависимости в пространство имен вашего плагина. Дэнни ван Кутен сделал это для одного из своих плагинов. Однако это не идеально. Каждый раз, когда он обновляет свои зависимости, ему приходится просматривать все файлы и снова менять пространства имен. Теперь это не такая большая задача для относительно небольшой библиотеки, такой как Pimple, но масштабная задача для более крупных библиотек.

Однако это можно сделать только с пространствами имен, поэтому вам также придется сделать так, чтобы ваш плагин требовал PHP 5.3+. Я не буду врать, я думаю, что каждый плагин должен начать делать это рано или поздно, но это определенно то, что вам нужно учитывать, когда вы решите это сделать.

Каким было бы идеальное решение, если оно существует?

Идеальной ситуацией было бы использование какого-то менеджера зависимостей. Есть, конечно, Composer, наиболее часто используемый менеджер зависимостей. Composer очень сложно, если вообще возможно, использовать подавляющему большинству пользователей WordPress. В конце концов, это инструмент разработчика.

WordPress должен сделать это проще для своих конечных пользователей, в то же время позволяя разработчикам использовать практически любой пакет, который они хотят. С этой мыслью я начал собирать плагин WordPress Composer Installer, который выполняет всю тяжелую работу Composer, в то время как люди устанавливают плагины, как обычно. Как только я смогу закончить это, я правильно интегрирую его во весь процесс установки плагина.

Теперь, может быть, однажды это можно будет интегрировать в ядро ​​​​WordPress. Впереди долгий путь, но доказательство концепции уже работает.

Вывод

Если вы дочитали до этого места, прежде всего: Спасибо. Во-вторых, я надеюсь, теперь вы понимаете, что это в конечном итоге станет проблемой. Наша текущая ситуация очень расстраивает, потому что у нас просто нет необходимых инструментов. Тем не менее, я считаю важным, чтобы мы продолжали говорить об этом и удостоверились, что все мы, как разработчики WordPress, понимаем потенциальные проблемы, вызванные конфликтующими сторонними зависимостями в нашем коде.

Наконец, я хочу еще раз отметить, что это не проблема Composer. Это проблема WordPress.