2013-03-23 3 views
0

Можно ли получить имя вызываемой функции в деструкторе?Получить имя вызываемой функции в деструкторе

class My_class { 

    function my_func() { 
     echo 'Hii'; 
    } 

    function your_func() { 
     echo 'Hii'; 
    } 

    function __destruct() { 
     echo $the_called_func_name; 
    } 
} 


$bar = new my_class(); 
$bar->my_func(); 

возможно получить имя «my_func» в деструктор?

если мы использовали

echo __FUNCTION__; 

это даст

__destruct 

я хочу

my_func 
+0

Не могли бы вы объяснить, что вы хотите достичь? Другими словами: почему? Я уверен, что это не обязательно –

+1

его просто для регистрации того, какая функция была присоединена. Вместо вызова функции журнала в каждой функции. – Dino

ответ

0

Да,

class My_class { 

    function my_func() { 
     echo 'Hii'; 
    } 

    function your_func() { 
     echo 'Hii'; 
    } 

    function __destruct() { 
     self::my_func(); 
     // my_func called 
    } 
} 


$bar = new my_class(); 
$bar->my_func(); 

Если вы имеете в виду имя функции, используйте функцию __call для функции объекта и __callStatic для статической функции.

2

Да, это возможно. Поскольку my_func динамична, вы можете использовать функцию перегрузки (a.k.a магическим способом) __call()

class My_Class 
{ 

    private $methods = array(); 


    public function __call($method, array $args) 
    { 
     array_push($this->methods, $method); 
    } 

    public function getMethods() 
    { 
     return $this->methods; 
    } 

    public function __destruct() 
    { 
     // Off course, you should improve this 
     print_r($this->getMethods()); 
    } 
} 

// Usage: 

$foo = new My_Class(); 
$foo->my_func(); // Output Array(0 => 'my_func') 
1

его только для входа, что какая функция accesed. Вместо вызова функции журнала в каждой функции.

Это нелегко без добавления кода к методам или с помощью отдельного инструмента для отладки и профилирования.

Обратите внимание, что предлагаемые решения с __call не работают с существующими общедоступными методами, в конце концов, это будет усложняться, чем просто добавлять log(__METHOD__) к каждому методу.

Что вы ищете, это в основном Aspect Oriented Programming (AOP), который не очень поддерживается в PHP. Структура Flow3 использует аннотации и отражение для динамического добавления аспектов. Их Logging Example является прекрасной иллюстрацией вашего случая использования:

namespace Example\MyPackage; 

/** 
* A logging aspect 
* 
* @Flow\Aspect 
*/ 
class LoggingAspect { 

     /** 
     * @var \TYPO3\Flow\Log\LoggerInterface A logger implementation 
     */ 
     protected $logger; 

     /** 
     * For logging we need a logger, which we will get injected automatically by 
     * the Object Manager 
     * 
     * @param \TYPO3\Flow\Log\SystemLoggerInterface $logger The System Logger 
     * @return void 
     */ 
     public function injectSystemLogger(\TYPO3\Flow\Log\SystemLoggerInterface ⏎ 
       $systemLogger) { 
       $this->logger = $systemLogger; 
     } 

     /** 
     * Before advice, logs all access to public methods of our package 
     * 
     * @param \TYPO3\Flow\AOP\JoinPointInterface $joinPoint: The current join point 
     * @return void 
     * @Flow\Before("method(public Example\MyPackage\.*->.*())") 
     */ 
     public function logMethodExecution(\TYPO3\Flow\AOP\JoinPointInterface $joinPoint) { 
       $logMessage = 'The method ' . $joinPoint->getMethodName() . ' in class ' . 
         $joinPoint->getClassName() . ' has been called.'; 
       $this->logger->log($logMessage); 
     } 
} 

Важным направлением является следующим:

@Flow\Before("method(public Example\MyPackage\.*->.*())") 

он говорит рамки для вызова logMethodExecution перед любым вызовом метода в любом классе Example\MyPackage имен.

Итак, с Flow3 вы можете это сделать. Но реализация подобного поведения самостоятельно без рамки AOP неизбежно завершится неудачей.

Смежные вопросы