Skip to content

Instantly share code, notes, and snippets.

@MarceauKa
Created October 29, 2019 18:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MarceauKa/bc96c460ae8404377f66ec1cedbdf135 to your computer and use it in GitHub Desktop.
Save MarceauKa/bc96c460ae8404377f66ec1cedbdf135 to your computer and use it in GitHub Desktop.
PHP get instance caller
<?php
trait Tracable
{
protected $__call = null;
protected $__call_stack = [];
public static function call(...$args)
{
$class = new ReflectionClass(get_class());
$self = $class->newInstanceArgs($args);
$self->__call = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['class'];
$traits = array_values(class_uses($self->__call));
$interfaces = array_values(class_implements($self->__call));
$parents = array_values(class_parents($self->__call));
$self->__call_stack = array_merge($traits, $interfaces, $parents);
return $self;
}
public function __called($class): ?string
{
return $this->__call;
}
public function __calledStack(): array
{
return $this->__call_stack;
}
public function __isCalledFrom($class): bool
{
if (is_object($class)) {
$class = get_class($class);
}
return $class === $this->__call
|| in_array($class, $this->__call_stack);
}
}
interface CallerInterface {}
trait CallerTrait {}
class ParentCaller {}
class Caller extends ParentCaller implements CallerInterface
{
use CallerTrait;
public $dependent;
public function __construct()
{
$this->dependent = Dependent::call();
}
}
class Dependent
{
use Tracable;
}
$caller = new Caller();
var_dump(
$caller->dependent->__isCalledFrom(Caller::class), // true
$caller->dependent->__isCalledFrom(CallerInterface::class), // true
$caller->dependent->__isCalledFrom($caller), // true
$caller->dependent->__isCalledFrom(CallerTrait::class) // true
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment