简体   繁体   English

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

[英]Autoloading as “mock” class in php

Lets suppose I want to auto load classes, so far thats normal. 假设我要自动加载类,到目前为止,这很正常。 Now, lets suppose we are in "test" environment. 现在,假设我们处于“测试”环境中。 I want to load other classes instead, this classes act just like others, but with some modifications. 我想加载其他类,但这些类的行为与其他类相同,但进行了一些修改。 So, originally 所以,原来

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

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

and what I want: 和我想要的是:

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();

so somewhat "renaming" method should be used, instead of refactoring the code. 因此应该使用某种“重新命名”方法,而不是重构代码。

use get_declared_classes and eval eg 使用get_declared_classeseval例如

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

Updated (and messy) 更新(并且混乱)
A couple of possible ways of tackling your issue - may be worth a closer look. 解决问题的几种可能方法-值得仔细研究。 At the bottom, there is also a personal consideration/suggestion. 在底部,还有一个个人考虑/建议。

The shortest of short fixes might just apply in your case: instead of having PHP's autoloader looking for the .php extension, you could set it so that, when testing your code, you are in fact looking for files ending on dev.php , so that class A , when passed as a string to the autoloarder becomes Adev.php : 最短的简短修复可能只适用于您的情况:您可以将其设置为,使得在测试代码时实际上正在寻找以dev.php结尾的.php ,而不是让PHP的自动加载器寻找.php扩展名。将该类A作为字符串传递给自动装货商时,将成为Adev.php

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

Not sure, but perhaps use getenv() to determine if you're running on test/dev or production environment, and based on that register different autoloaders? 不确定,但是也许可以使用getenv()来确定您是在测试/开发环境还是生产环境上运行,并基于该注册使用其他自动加载器? spl_autoload_register is a handy function for that: 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');
}

Of course, there will be a bit more to it, than just these few lines. 当然,除了这几行之外,还有更多的事情要做。 But with this approach, you don't need differently named classes: A will be loaded form either the dev or live file, based on the autoloader/extension. 但是,使用这种方法,您无需使用其他名称的类: A将基于自动加载器/扩展名从dev或live文件加载。
That way, you can at least keep type-hinting all the way through, without any issues. 这样,您至少可以一直保持类型提示,而不会出现任何问题。 Of course, maintainability will be even more of a nightmare: Edit 1 file, make sure to edit the other one, too. 当然,可维护性将成为噩梦:编辑1个文件,并确保也编辑另一个文件。

That's why I must say, personally, I wouldn't go through all this trouble of writing different classes for test & live environments. 这就是为什么我个人必须说,我不会为编写用于测试和现场环境的不同类而遇到的所有麻烦。 At one point, you'll run into trouble with that... 一方面,您会遇到麻烦...
Suppose you fix a bug in test, but fail to edit the production version? 假设您修复了测试中的错误,但是无法编辑生产版本? Or the other way 'round... I think you're better off spending a little time in setting up a decent debugger and test environment that will work with the same code, but (for example) not the actual production databases. 或以另一种方式“轮流……”我认为您最好花一点时间来建立一个像样的调试器和测试环境,该环境使用相同的代码,但(例如)不是实际的生产数据库。

Useful links: 有用的链接:

Have you considered using namespaces? 您是否考虑过使用名称空间? The code that follows is probably not 100% correct, but the gist of it would be: 后面的代码可能不是100%正确,但是要点是:

# A.php

class A {...}

# ADev.php

class ADev {...}

# script.php

use ADev as A;

$a = new A; # of class ADev

See: 看到:

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

Have you considered a simple solution rather than a complex one? 您是否考虑过简单的解决方案而不是复杂的解决方案?

Make Class A do what ADev does ie include the logging function and forget about duplicating all your classes. 使类A进行ADev的操作,即包括日志记录功能,而不必复制所有类。

Make the something:: class test a enviroment variable or a simple config variable. 做一些事情:类测试一个环境变量或一个简单的配置变量。 So something::debug tests $DO_I_WANT_DEBUGGING_ON = TRUE, if it is then you do the logging otherwise you do not. 所以,某事:: debug测试$ DO_I_WANT_DEBUGGING_ON = TRUE,如果是,则执行日志记录,否则不执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM