是的,我知道依赖项应该传递给构造函数。我不是在问编码风格或该做什么和不该做什么。
我的应用程序中的许多类都与数据库驱动程序类的实例相关联。为此,我使用 PHP 的后期静态绑定创建了一个抽象工厂类。该类的唯一成员是保存驱动程序引用的属性。它看起来像这样:
abstract class Factory {
static private $__instances;
static private $__default_driver;
protected $_driver;
static public function getInstance ( \Database\Driver $driver = null ) {
if ( ! isset($driver) ) {
if ( ! isset(self::$__default_driver) ) {
require ( \Core\Options::$database_driver[ 'path' ] );
self::$__default_driver = new \Core\Options::$database_driver[ 'class' ]( \Core\Options::$database_options );
}
$driver = self::$__default_driver;
}
$schema = $driver->getDatabase();
$class = get_called_class();
if ( ! isset(self::$__instances[ $schema ][ $class ]) ) {
self::$__instances[ $schema ][ $class ] = new $class( $driver );
self::$__instances[ $schema ][ $class ]->_driver = $driver;
}
return self::$__instances[ $schema ][ $class ];
}
}
正如您所看到的,当我创建派生类的实例时,我将驱动程序的实例传递给其构造函数。然后设置属性。如果可能的话,我想通过先设置属性然后调用构造函数来扭转这种情况。这样,派生类不需要实现构造函数,也不需要担心调用父方法(如果需要)。
我已经调查过Reflection
API 可以做到这一点,但我似乎找不到任何可行的方法。最多Dependency Injection
我发现链接实际上使用了构造函数。这需要在 PHP 5.3 上运行。
对于那些坚持认为这是不可能的人来说,在 PHP 5.4 中可以轻松完成 http://www.php.net/manual/en/reflectionclass.newinstancewithoutconstructor.php#108466 using ReflectionClass::newInstanceWithoutConstructor()
.
class Foo {
public function __construct() {
echo 'foo';
}
}
$r = new ReflectionClass('Foo');
$o = $r->newInstanceWithoutConstructor();
$o->bar = 'baz';
$o->__construct();
从 PHP 5.4 开始,这是可能的。
但说实话:不。就是不行。不。实例化对象时,应始终调用对象的构造函数。不早(显然),也不晚。构造函数和对象其余部分的适当封装保证了对象始终处于一致的状态。一旦你开始使用它拆开ReflectionClass
无法再对对象的状态做出任何保证,并且健全性和类型安全性也将被抛诸脑后。
因为你使用的是 5.3,所以你很幸运,那里没有办法做到这一点。如果你发现自己陷入了这样的困境,那么你就做错了。已经编写了非常复杂的程序,无需欺骗 PHP 的对象模型来延迟构造函数调用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)