Современный способ переписывания файлов 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

Ответы:



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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.