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

From: Date: Tue, 06 Dec 2011 18:37:22 +0000
Subject: note 93799 deleted from function.get-called-class by danbrown
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-184944@lists.php.net to get a copy of this message
Note Submitter: laurence+nospam at sol1 dot com dot au ---- I've made some additions to mucahitkahveci's method, but ended up re-writing it to suit certain needs and conventions. It passes the example test cases on the late static bindings page with the <?php static::funtion_name() ?> calls converted to <?php $static_class = get_called_class(); call_user_func(array($static_class,'function_name')); ?> I tested it in PHP 5.2.4 and came across no discrepancies from the 5.3 behavior, however the more eyes the better. Also, I've included the edge case where a static property can be called on a class e.g. <?php class A { public function __get($var) { return get_class_name(); } } $instance = new A(); echo $instance->foo; ?> However this probably doesn't cover all edge cases, so the function still needs work. And here it is... <?php /******************************** * Retro-support of get_called_class() * Tested and works in PHP 5.2.4 * http://www.sol1.com.au/ ********************************/ 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 '::': $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"); } } } ?> [EDIT BY danbrown AT php DOT net: Contains a fix provided by (webmaster AT easy DASH coding DOT de) on 10-NOV-09 with the following explanation: since method calls are caseinsensitive you should use stripos instead of strpos. Otherwise you will end up with a "Undefined offset: -1" notice and the error "Could not find caller class."]

« previous php.notes (#184944) next »