[英]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_classes
和eval
例如
$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.