note 106763 added to function.get-called-class
| From: | xaguilars at gmail dot com | Date: | Mon, 05 Dec 2011 10:24:48 +0000 |
| Subject: | note 106763 added to function.get-called-class | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-184899@lists.php.net to get a copy of this message | ||
I've updated the get_called_class support function for PHP 5.2.
It was entering in a infinite loop when I was trying to call get_called_class() inside a function
called via call_user_func() or call_user_func_array().
It's tricky, but it works for me as expected. Tested in PHP 5.2.17
<?php
if (!function_exists('get_called_class')) {
function get_called_class($bt = false, $l = 1) {
if (!$bt)
$bt = debug_backtrace();
if (!isset($bt[$l]))
throw new Exception("Cannot find called class -> stack level too deep.");
if (!isset($bt[$l]['type'])) {
throw new Exception('type not set');
} else {
switch ($bt[$l]['type']) {
case '::': {
if (!isset($bt[$l]['file'])) {
if (isset($bt[$l + 1]) && isset($bt[$l +
1]["function"]) && isset($bt[$l + 1]["args"]) && isset($bt[$l +
1]["args"][0])) {
$btcall = $bt[$l + 1];
if (($btcall["function"] ==
"call_user_func")||($btcall["function"] == "call_user_func_array")) {
$func = $btcall["args"]["0"];
if (is_array($func))
return $func[0];
else {
$func = explode("::", $func);
return $func[0];
}
}
}
//if(isset($bt[$l]['class'])) return
$bt[$l]['class']; //this would return wrong class
//echo $l;print_r($bt);die();
throw new Exception("Could not find caller class: maybe you used a
variable to reference the class?.");
}
$lines = file($bt[$l]['file']);
$i = 0;
$callerLine = '';
do {
$i++;
$callerLine = $lines[$bt[$l]['line'] - $i] . $callerLine;
} while (stripos($callerLine, $bt[$l]['function']) === false);
preg_match('/([a-zA-Z0-9\_]+)::' . $bt[$l]['function'] .
'/', $callerLine, $matches);
if (!isset($matches[1])) {
// must be an edge case.
throw new Exception("Could not find caller class: originating
method call is obscured.");
}
switch ($matches[1]) {
case 'self':
case 'parent':
return get_called_class($bt, $l + 1);
default:
return $matches[1];
}
}
// won't get here.
case '->': {
switch ($bt[$l]['function']) {
case '__get':
// edge case -> get class of calling object
if (!is_object($bt[$l]['object']))
throw new Exception("Edge case fail. __get called on non
object.");
return get_class($bt[$l]['object']);
default: return $bt[$l]['class'];
}
}
default: throw new Exception("Unknown backtrace method type");
}
}
}
}
?>
----
Server IP: 69.147.83.197
Probable Submitter: 95.39.226.212
----
Manual Page -- http://www.php.net/manual/en/function.get-called-class.php
Edit -- https://master.php.net/note/edit/106763
Del: integrated -- https://master.php.net/note/delete/106763/integrated
Del: useless -- https://master.php.net/note/delete/106763/useless
Del: bad code -- https://master.php.net/note/delete/106763/bad+code
Del: spam -- https://master.php.net/note/delete/106763/spam
Del: non-english -- https://master.php.net/note/delete/106763/non-english
Del: in docs -- https://master.php.net/note/delete/106763/in+docs
Del: other reasons-- https://master.php.net/note/delete/106763
Reject -- https://master.php.net/note/reject/106763
Search -- https://master.php.net/manage/user-notes.php