如何跟踪嵌套对象创建

时间:2016-06-30 16:51:40

标签: php inheritance nested php-7

我有一个父类和多个继承它的子项。

有些孩子会打电话给其他孩子。但它们并不总是被称为嵌套。

class Parent { }

class Child extends Parent {
    public function run() {
        // Kid nested inside Child. Do not open DB transaction
        $a = (new Kid())->run();
    }
}

class Kid extends Parent {
    public function run() {
        // @todo Open DB transaction if not nested
    }
}

// Kid not nested. Open DB transaction
(new Kid())->run();

是否有一种有效的方法让Kid对象知道(不是由我手动告知)它是在Child内部还是外部实例化的?

2 个答案:

答案 0 :(得分:1)

在不知道代码的结构如何的情况下,我能想到的唯一方法是创建两个子类(我们称之为Kid1Kid2)。他们所要做的只是

class Kid1 extends Kid {}

然后你会打电话给

class Child extends Parent {
    public function run() {
        // Kid nested inside Child. Do not open DB transaction
        $a = (new Kid1())->run();
    }
}

class Kid extends Parent {
    public function run() {
        // @todo Open DB transaction if not nested
        if($this instanceof Kid2) // Open DB
    }
}

是的,您仍然在告诉Kid什么叫它,但它符合OOP的做法

答案 1 :(得分:0)

使用debug_backtrace功能跟踪run方法调用 在debug_backtrace()中所有可能返回的元素中,class项应该在您的情况下跟踪。
如果堆栈跟踪中有多个class项 - 它是一个“嵌套”调用:

class Parent { }

class Child extends Parent {
    public function run() {
        // Kid nested inside Child. Do not open DB transaction
        $a = (new Kid())->run();
    }
}

class Kid extends Parent {
    public function run() {
        $trace = debug_backtrace();
        // Note that 'array_column' function is available since PHP 5.5        
        if (count(array_column($trace, 'class')) > 1) {
            // Do not open DB transaction
            // do another job
        } else {
            // Open DB transaction
        }
        unset($trace);
    }
}

// Kid not nested. Open DB transaction
(new Kid())->run();

(new Child())->run(); // Kid nested inside Child. Do not open DB transaction  

http://php.net/manual/en/function.debug-backtrace.php