如何查找所有对象实例?

时间:2014-01-13 13:16:10

标签: php

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范围的实施。

2 个答案:

答案 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.