Reputation: 25569
I have a parent class and multiple children that inherit from it.
Some children will call other children within themselves. But they are not always called nested.
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();
Is there an efficient way for the Kid
object to know (without being manually told by me) whether it was instantiated inside or outside of Child
?
Upvotes: 0
Views: 67
Reputation: 92854
Use debug_backtrace
function to trace the run
method calls.
Among all possible returned elements from debug_backtrace()
, class
item should be traced in your case.
If there's more than one class
item within stack trace - it's a "nested" invocation:
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
Upvotes: 0
Reputation: 31654
Without knowing how your code is structured, the only way I could think of is to make two child classes (we'll call them Kid1
and Kid2
). All they would do is
class Kid1 extends Kid {}
Then you would call
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
}
}
Yes, you're still telling Kid
what called it, but it fits with OOP practices
Upvotes: 1