note 106763 deleted from function.get-called-class by danbrown

From: Date: Tue, 06 Dec 2011 18:37:47 +0000
Subject: note 106763 deleted from function.get-called-class by danbrown
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-184945@lists.php.net to get a copy of this message
Note Submitter: xaguilars at gmail dot com ---- 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"); } } } } ?>

« previous php.notes (#184945) next »