class Bar {
public function defer () {
// Here, I want to replace all instances of $foo with new Baz instance.
};
}
class Baz {
public function test () {
echo 'Test';
}
}
$foo = new Bar();
$foo->defer();
$foo->test();
有没有办法找到当前对象的所有实例并将其替换为另一个?这实际上是eq。重载实例$this
变量。
请参阅答案https://stackoverflow.com/a/21092438/368691,了解仅限于$ GLOBALS范围的实施。
答案 0 :(得分:0)
我需要一些时间才能得到你想要做的事情。你所尝试的是否会破坏良好的编程原则,尤其是责任问题。
为什么一个组件应该更改已创建变量的数据类型,而没有创建变量的代码知道?
答案 1 :(得分:0)
如果假设变量只能在全局范围内,则解决方案非常简单:
<?php
class Bar {
public function defer () {
array_walk_recursive($GLOBALS, function (&$e) {
if ($e instanceof $this) {
$e = new Baz();
}
});
}
}
class Baz {}
$bar = new Bar();
$bar->defer();
var_dump( $bar );
将产生:
object(Baz)#4 (0) {
}
然而,这个答案更多的是寻找最终答案的指导,而不是一个明确的解决方案。
示例应用程序:
<?php
class PDODeferred extends \PDO {
private
$constructor,
$attributes = [];
public function __construct ($dsn, $username = null, $password = null, array $driver_options = []) {
$this->constructor = [$dsn, $username, $password, $driver_options];
}
public function exec ($statement) {
$db = $this->connect();
return $db->exec($statement);
}
public function setAttribute ($attribute, $value) {
$this->attribute[$attribute] = $value;
}
private function connect () {
$db = new \PDO($this->constructor[0], $this->constructor[1], $this->constructor[2], $this->constructor[3]);
foreach ($this->attributes as $attribute => $value) {
$db->setAttribute($attribute, $value);
}
array_walk_recursive($GLOBALS, function (&$e) use ($db) {
if ($e instanceof $this) {
$e = $db;
}
});
return $db;
}
}
$db = new PDODeferred('mysql:dbname=foo');
// No connection is made to the DB yet.
$db->exec("SELECT 1;");
// Connection is made.
$db->exec("SELECT 1");
// $db is now regular PDO instance.