Pojawiła się dziś konieczność eleganckiego mierzenia czasu wykonania niektórych metod. Pierwotnie wyglądało to tak:
$timer_id = TIME::start();
$this->slowMethod();
echo TIME::stop($timer_id);
Jeśli w trakcie testów trzeba było pododawać pomiary czasu to kod nagle strasznie puchł i wywołania metod ginęły w gąszczu wpisów pomiarowych.
Pojawił się pomysł obejścia problemu tak:
$this->logTime('slowMethod');
Problem generuje to taki, że niewygodnie dodaje się i usuwa tego typu dodatki, łatwo zostawić gdzieś jakieś śmiecie.
W końcu problem znalazł takie rozwiązanie:
$this->_LOG_slowMethod();
Dodanie czy usunięcie prefixu jest dość proste (można z automatu search/replace). Kod pozostaje czytelny, jedynym mankamentem jest brak możliwości skoku do kodu metody w Eclipse poprzez ctrl+kliknięcie na nazwie metody.
Cały patent polega na przechwyceniu wywołania nieistniejącej metody poprzez __call.
Przykładowa implementacja:
function __call($function,$params)
{
$ret = null;
$prefix = preg_replace('/^(_.+_).*/','\\1',$function);
$method = str_replace($prefix,'',$function);
switch($prefix)
{
case '_LOG_':
$timer_id = TIME::start();
$ret = @call_user_func_array(array(&$this,$method),$params);
echo TIME::stop($timer_id);
break;
case '_DEBUG_':
$ret = @call_user_func_array(array(&$this,$method),$params);
printr($ret);
break;
}
return $ret;
}
Kod łatwo rozbudować o dowolne prefixy i bardziej złożone funkcjonalności ;D