Как получить namespase класса который вызвал метод в другом классе?

Возможно ли получит namespase класса который вызывал метод в классе?

namespace App\B\ClassB;

class B{
    public function call(){
        //this function was called by the class namespace which App\A\ClassA
        return 1;
    }
}

namespace App\A\ClassA;
use App\B\ClassB\B;
class A{
    public function use_f(){
        $b = new B();
        $b->call();
    }
}

Хочу в

public function call()

получить namespase класса который вызвал этот метод, но пошарив по документации так и не понял как это сделать. Возможно ли это вообще? если да то как?

PHP 7.4.18


Ответы (1 шт):

Автор решения: UrfinJuezz

Очень короткий ответ - https://www.php.net/manual/ru/function.debug-backtrace.php

Немного подлиннее:

<?php
namespace App;
function callerNamespace():?string{
    $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);
    if (!array_key_exists(2,$trace)){
        return null;
    }
    $callerClass = $trace[2]['class'];
    $callerNamespace = substr($callerClass, 0, strrpos($callerClass, '\\')) ;
    return $callerNamespace;
}

namespace App\B\ClassB;

class B{
    public function call(){
        print_r(\App\callerNamespace());
        echo PHP_EOL;
        return 1;
    }
}

namespace App\A\ClassA;
use App\B\ClassB\B;
class A{
    public function use_f(){
        $b = new B();
        print_r("call from another class" . PHP_EOL);
        $b->call();
    }
}


$a = new A();
$a->use_f();

$b = new \App\B\ClassB\B();
print_r("call outside another class"  . PHP_EOL);
$b->call();
?>

Как видите если вызвать B::call() не из другого класса, то функция callerNamespace() вернёт null.

Если интересно моё мнение: Если у вас возникает необходимость менять поведение метода в зависимости от того откуда он был вызван - скорее всего у вас проблема в архитектуре. Лучше перепишите ваш код так чтобы использовать разные сервисы в разных неймспейсах, чтобы поведение было более явным.

→ Ссылка