我有一个父类和多个继承它的子项。
有些孩子会打电话给其他孩子。但它们并不总是被称为嵌套。
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
内部还是外部实例化的?
答案 0 :(得分:1)
在不知道代码的结构如何的情况下,我能想到的唯一方法是创建两个子类(我们称之为Kid1
和Kid2
)。他们所要做的只是
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