note 97344 deleted from function.get-called-class by danbrown
| From: | danbrown@php.net | Date: | Thu, 15 Apr 2010 12:54:14 +0000 |
| Subject: | note 97344 deleted from function.get-called-class by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-168270@lists.php.net to get a copy of this message | ||
Note Submitter: thomas at weblizards dot de
----
I added a little cache to Laurence's work, so the function doesn't have to parse the
sourcefile each time it is called:
<?
$get_called_class_cache_file = "/path/to/writeable/file.php";
if(file_exists($get_called_class_cache_file)) {
$GLOBALS["get_called_classes"] = include_once($get_called_class_cache_file);
} else {
$GLOBALS["get_called_classes"] = array();
file_put_contents($get_called_class_cache_file,'<? return
'.var_export($GLOBALS["get_called_classes"], 1).';');
}
function get_called_class($bt = false, $l = 1) {
global $get_called_class_cache_file;
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");
switch ($bt[$l]['type']) {
case "::":
if (array_key_exists($bt[$l]['file'], $GLOBALS["get_called_classes"])) return
$GLOBALS["get_called_classes"][$bt[$l]['file']];
$lines = file($bt[$l]['file']);
$i = 0;
$callerLine = '';
$class_name = "";
do {
$i++;
$callerLine = $lines[$bt[$l]['line']-$i] . $callerLine;
} while (stripos($callerLine,$bt[$l]['function']) === false);
$matches = array();
preg_match('/([a-zA-Z0-9\_]+)::'.$bt[$l]['function'].'/',
$callerLine, $matches);
if (!isset($matches[1])) throw new Exception ("Could not find caller class: originating
method call is obscured."); // must be an edge case.
switch ($matches[1]) {
case 'self':
case 'parent':
$class_name = get_called_class($bt,$l+1);
break;
default:
$class_name = $matches[1];
break;
}
$GLOBALS["get_called_classes"][$bt[$l]['file']] = $class_name;
file_put_contents($get_called_class_cache_file,'<? return
'.var_export($GLOBALS["get_called_classes"], 1).';');
return $class_name;
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");
}
}
?>