Современный способ переписывания файлов lib

21

Проблема хорошо известна: libклассы загружаются исключительно через автозагрузчик, и мы не можем изменить их, кроме:

  • Копирование их полностью в codePool, который проверяется раньше, чем lib.
  • Установка автозагрузчика PSR-0 , указание карты классов автозагрузки, а затем полное копирование файла в эту структуру папок. [мое текущее решение]

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

Теперь очевидно, что есть потенциальные решения этой проблемы, но все они имеют свои собственные проблемы:

  • Пройдите маршрут AOP и используйте основанную на PHP библиотеку, такую ​​как Go! АОП : В последний раз, когда я проверял, для этого потребуется, чтобы классы Magento загружались автозагрузчиком композитора, а не только один из них был доступен. Flyingmana проделала определенную работу в этой области, но она определенно не готова к использованию, и мои потребности более насущны. Я также хочу отправить как расширение, и это потребовало бы больше настройки композитора.
  • Пройдите маршрут AOP и используйте собственное расширение PHP : вероятно, наиболее выгодное на данный момент, но для этого потребуется установить отдельное расширение, не говоря уже о том, что оно не будет работать с HHVM.
  • Используйте PHP classkit и / или runkit : это еще одно собственное расширение PHP, поэтому у него та же проблема, что и выше.
  • Патч-сайты вызовов используют мою собственную \Danslo\Varien_Xверсию namespaced ( ), а затем расширяются от оригинала ( \Varien_X): слишком много сайтов для патчей, чтобы исправить, и это потребовало бы глупого количества переписываний. Не вариант.
  • Сверните мое собственное: должно быть возможно:

    1. Напишите мой собственный автозагрузчик.
    2. Скопируйте исходный класс в отдельную папку ( {root_dir}/var/tmp), оберните его namespace \Magento { < original contents > }.
    3. Включите этот файл.
    4. Включить мой измененный класс OriginalClass extends Magento\OriginalClass {}

Недостаток этого очевиден: динамическая генерация кода, регулярные выражения, небольшие накладные расходы на загрузку переписанных классов. Но я почти уверен, что на этом этапе было бы лучше копировать ~ 5000 строк кода, когда я просто хочу коснуться / добавить ~ 100 строк.

Я знаю, что спрашиваю много, но есть ли что-то современное и относительно чистое, что помогает решить эту проблему?

Дэниел Слооф
источник
1
Вы уже нашли решение для наблюдателей от Alans? stackoverflow.com/a/4636662/158325
B00MER

Ответы:

9

Решили реализовать Go! AOP рамки в Magento.

Смотрите Danslo_Aop на github.

Дэниел Слооф
источник
2

Пройдите маршрут AOP и используйте основанную на PHP библиотеку, такую ​​как Go! АОП: В последний раз, когда я проверял, для этого потребуется, чтобы классы Magento загружались автозагрузчиком композитора, а не только один из них был доступен. Flyingmana проделала определенную работу в этой области, но она определенно не готова к использованию, и мои потребности более насущны. Я также хочу отправить как расширение, и это потребовало бы больше настройки композитора.

Я хочу добавить, что Go! AOP Framework может работать без композитора, я могу помочь с настройкой (просто создайте для этого проблему на github). Composer нужен только для прозрачной интеграции с современными приложениями.

Просто замените include $filenameили require $filenameв вашем загрузчике include FilterInjectorTransformer::rewrite($filename)и настройте автозагрузчик для Go! Сам АОП.

Лисаченко
источник
1
Вау круто. Я обязательно попробую это.
Даниэль Слооф
0

Перейти с подходом автозагрузчика. Переименуйте / все / классы в lib с префиксом:

find lib -name '*.php' -exec sed -e 's,^class ,class Oldlib_,' {} +

Запускайте следующий «фиксатор переопределения» каждый раз, когда вы добавляете файл в mylib:

find lib -name '*.php' -print | while read FILE
do
    classname=$(echo ${FILE}|sed -e 's,^lib/,,' -e 's,\.php$,,' -e 's,/,_,g')
    if [ ! -f mylib/${FILE#lib/} ]; then
        # ensure is_a works by providing a stub with correct classname
        echo "class ${classname} extends Oldlib_${classname} {}" > mylib/${classname}.php
    elif [ -f mylib/${classname}.php ]; then
        # we have a new override, but the old file still exists
        rm mylib/${classname}.php
    fi
done

Научите автозагрузчик возвращаться, mylib/${classname}.phpесли он существует, и mylib/full/path/to/class.phpесли он не существует и mylib/full/path/to/class.phpделает.

Вставьте свои переопределения mylib/full/path/to/class.phpи расширьте версию Oldlib_.

Обновления просто откатывают префикс в lib / upgrade его, повторно применяют префикс, перезапускают корректор переопределения. Осталось только то, что было перемещено lib/и ранее было переопределено, но это не связано с проблемой. Ваша проблема может быть в количестве файлов в каталоге mylib /, но я надеюсь, что вы можете решить эту проблему :).

Мелвин
источник
Этот подход вводит много рисков и вещей, которые необходимо поддерживать, особенно в отношении обновлений. Это также нарушает правило «не трогай ядро». Кроме того, он не подходит для разработчиков расширений.
биплогия
При всем уважении, хотя ваше решение работает ... оно не может рассматриваться как a modernспособ переписывания файлов lib. Императивное программирование - старая школа;)
Eddie B
0

Также вы можете определить пользовательский поток и добавить его поверх пути автозагрузки. Работает с любым автозагрузчиком и требует минимального принятия. См пример

Канди
источник