重写lib文件的现代方法


21

这个问题是众所周知的:lib类是通过自动加载器专门加载的,除以下内容外,我们不能更改它们:

  • 将它们完全复制到lib之前检查的codePool中。
  • 安装PSR-0自动加载器,指定自动加载类映射,然后将文件完全复制到该文件夹​​结构中。[我目前的解决方案]

我处于困境中,因为我想潜在地触摸其中的许多文件-但是出于我的理智和商店的稳定性/可升级性的考虑,我不想复制整个库类。

现在显然可以找到解决该问题的方法,但是它们都有自己的一系列问题:

  • 进行AOP路由,并使用基于PHP的库(如Go!)!AOP:最后我检查了这将要求Magento类由作曲家自动加载器加载,而不仅仅是可用的。Flyingmana 在这方面做过一些工作,但肯定还不能用于生产,我的需求更加迫切。我还想将其作为扩展发布,这将需要更多的作曲家设置。
  • 进行AOP路由并使用本机PHP扩展:这可能是目前最有利的扩展,但它需要安装单独的扩展,更不用说它不适用于HHVM。
  • 使用PHP的classkit和/或runkit:这是另一个本机PHP扩展,因此与上述问题相同。
  • 修补呼叫站点以使用我自己的命名空间(\Danslo\Varien_X)版本,然后从原始(\Varien_X)扩展:有太多的呼叫站点需要修补,这将需要大量的重写。没有选择。
  • 我自己说:应该有可能:

    1. 编写我自己的自动装带器。
    2. 将原始类复制到一个单独的文件夹({root_dir}/var/tmp),将其包装在中namespace \Magento { < original contents > }
    3. 包括该文件。
    4. 包括我修改过的课程 OriginalClass extends Magento\OriginalClass {}

显而易见的缺点是:动态代码生成,正则表达式,加载重写类的开销很小。但是我几乎可以确定,当我只想触摸/添加约100行时,它将胜过复制约5000行代码。

我知道我要问很多,但是是否有一些现代且相对干净的东西可以帮助解决此问题?


1
您找到Alans观察者解决方案了吗?stackoverflow.com/a/4636662/158325
B00MER 2014年

Answers:



2

进行AOP路由,并使用基于PHP的库(如Go!)!AOP:最后我检查了一下,这将要求Compener自动加载器加载Magento类,而不仅仅是可用的一种。Flyingmana在这方面做过一些工作,但肯定还不能用于生产,我的需求更加迫切。我还想将其作为扩展发布,这将需要更多的作曲家设置。

我要添加Go!AOP框架可以在没有作曲家的情况下工作,我可以提供配置帮助(只需为此在github上创建一个问题)。仅在与现代应用程序进行透明集成时才需要Composer。

只需将bootstrap中的include $filename或替换为require $filenameinclude FilterInjectorTransformer::rewrite($filename)然后为Go配置自动加载器即可!AOP本身。


1
喔不错哟。我一定会尝试的。
丹尼尔·斯洛夫

0

使用自动加载器方法。用前缀重命名lib中的/ all /类:

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 /中的前缀/升级它,重新应用该前缀,然后重新运行覆盖修复程序。剩下的是已被移入lib/并先前被覆盖的东西,但这与问题无关。您的问题可能是mylib /目录中的文件数,但是我相信您可以解决这个问题:)。


这种方法会带来很多风险和需要维护的地方,尤其是在升级方面。这也违反了“请勿触及核心”规则。此外,对于扩展程序开发人员来说,这不是一个可行的选择。
beeplogic 2014年

尽管您的解决方案可以正常工作,但是……不能视为a modern重写lib文件的方法。命令式编程是一门老派;)
Eddie B

0

您还可以定义自定义Stream,并将其添加到自动加载路径的顶部。它可以与任何自动装带器一起使用,并且需要最少的采用。看例子

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.