0

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

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

4 回答 4

2

使用get_declared_classeseval例如

$classes = get_declared_classes();
foreach ($classes as $class)
    eval("\$".$class." = new ".$class."();");
于 2013-04-27T15:52:07.680 回答
2

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

最短的简短修复可能只适用于您的情况:.php您可以设置它,以便在测试您的代码时,您实际上是在寻找以 结尾的文件dev.php,这样 class A,当通过作为自动装载机的字符串变为Adev.php

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

不确定,但可能用于getenv()确定您是在测试/开发环境还是生产环境中运行,并基于该注册不同的自动加载器?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将根据自动加载器/扩展从开发文件或实时文件加载。
这样,您至少可以一直保持类型提示,没有任何问题。当然,可维护性将更像是一场噩梦:编辑 1 个文件,确保也编辑另一个文件。

这就是为什么我必须说,就个人而言,我不会经历为测试和实时环境编写不同类的所有麻烦。在某一时刻,您会遇到麻烦……
假设您在测试中修复了一个错误,但未能编辑生产版本?或者反过来......我认为你最好花一点时间来设置一个体面的调试器和测试环境,它可以使用相同的代码,但(例如)不是实际的生产数据库。

有用的链接:

于 2013-04-27T15:54:57.270 回答
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

于 2013-04-27T15:52:05.577 回答
1

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

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

使 something:: 类测试环境变量或简单的配置变量。所以 something::debug 测试 $DO_I_WANT_DEBUGGING_ON = TRUE,如果是,那么你做记录,否则你不做。

于 2013-04-27T16:06:32.637 回答