在php中自动加载为“模拟”类

时间:2013-04-27 15:42:20

标签: php autoload

假设我想自动加载类,到目前为止这是正常的。现在,让我们假设我们处于“测试”环境中。我想加载其他类,这些类就像其他类一样,但有一些修改。所以,最初

class A
{
    public function method()
    {
        return rand(1,10);
    }

$a = new A(); // in the meantime autoloader finds and load class A
$a->method();

和我想要的:

class Adev
{
    public function method()
    {
        something::log ('method running');
        return rand(1,10);
    }
}

$a = new A(); // and then I dont need "A" class but "Adev"
$a->method();

应该使用“重命名”方法,而不是重构代码。

4 个答案:

答案 0 :(得分:2)

使用get_declared_classeseval例如

$classes = get_declared_classes();
foreach ($classes as $class)
    eval("\$".$class." = new ".$class."();");

答案 1 :(得分:2)

更新(和凌乱)
解决问题的几种可能方法 - 可能值得仔细研究。在底部,还有个人考虑/建议。

最短的修补程序可能只适用于您的情况:您可以设置它,以便在测试代码时,您实际上在寻找文件结束时,而不是让PHP的自动加载器查找.php扩展名。在dev.php上,以便类A作为字符串传递给自动加载器时变为Adev.php

if (RUNNING_ENV=== 'test')
{
    spl_autoload_extensions('dev.php');
}

不确定,但是可能使用getenv()来确定您是在test / dev或生产环境中运行,并根据该寄存器使用不同的自动加载器? spl_autoload_register是一个方便的功能:

function prodAutoload($class)
{
    //normal loading
}
function tstAutoload($class)
{
    $class .='Dev';
    //add Dev to className, proceed as you normally would?
}
if (getenv('RUN_ENV') === 'prod')
{
    spl_autoload_register('prodAutoload');
}
else
{
    spl_autoload_register('tstAutoload');
}

当然,除了这几行之外,还会有更多内容。但是使用这种方法,您不需要不同的命名类:A将根据自动加载器/扩展名从dev或live文件加载。
这样,你至少可以保持类型提示,没有任何问题。当然,可维护性将更加噩梦:编辑1个文件,确保编辑另一个文件。

这就是为什么我必须说,就个人而言,我不会经历所有为编写测试和编写不同课程的麻烦。现场环境。有一次,你会遇到麻烦...
假设您修复了测试中的错误,但无法编辑生产版本?或者反过来......我认为你最好花一点时间来设置一个像 使用相同代码的好的调试器和测试环境,但是(例如)没有实际的生产数据库。

有用的链接:

答案 2 :(得分:1)

您是否考虑使用命名空间?下面的代码可能不是100%正确,但它的要点是:

# A.php

class A {...}

# ADev.php

class ADev {...}

# script.php

use ADev as A;

$a = new A; # of class ADev

请参阅:

http://php.net/manual/en/language.namespaces.importing.php

答案 3 :(得分:1)

您是否考虑过一个简单的解决方案而不是一个复杂的解决方案?

让A类做ADev所做的事情,包括记录功能,忘记复制所有类。

使something :: class test成为环境变量或简单的配置变量。 所以有些东西:: debug测试$ DO_I_WANT_DEBUGGING_ON = TRUE,如果是,那么你就进行日志记录,否则就没有。