Created
January 28, 2013 20:06
-
-
Save bayleedev/4658562 to your computer and use it in GitHub Desktop.
Determines if a given method name can be responded to. Classes with magic methods should extend the method. Originally, I was going to have the default `$visibility` to null and auto-detect if it was an internal class or not, but that turned out to be rather slow. (https://gist.github.com/4658402)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace foo\bar\baz; | |
use ReflectionClass; | |
use ReflectionMethod; | |
use Exception; | |
use BadMethodCallException; | |
error_reporting(-1); | |
class foo { | |
/** | |
* Will determine if a method can be called. | |
* | |
* @param string $method Method name. | |
* @param integer $visibility Visibility (1 for public, 2 for public and | |
* protected, and 3 for all visibility) | |
* @return bool | |
*/ | |
public function respondsTo($method, $visibility = 0) { | |
$class = new ReflectionClass($this); | |
$types = array(); | |
$types[0] = ReflectionMethod::IS_PUBLIC; | |
$types[1] = $types[0] | ReflectionMethod::IS_PROTECTED; | |
$types[2] = $types[1] | ReflectionMethod::IS_PRIVATE; | |
foreach ($class->getMethods($types[$visibility]) as $reflectMethod) { | |
if ($reflectMethod->getName() === $method) { | |
return true; | |
} | |
} | |
return false; | |
} | |
public function foo() { | |
return; | |
} | |
protected function foobaz() { | |
return; | |
} | |
} | |
class foobar extends foo { | |
protected $_magicMethods = array(); | |
public function __construct() { | |
$this->_magicMethods = array( | |
'bar' => function() { | |
return; | |
}, | |
'baz' => function() { | |
return; | |
} | |
); | |
} | |
public function __call($method, $args) { | |
if (in_array($method, $this->_magicMethods, 1)) { | |
return $this->foo();; | |
} | |
throw new BadMethodCallException; | |
} | |
/** | |
* Custom check to determine if our given magic methods can be responded to. | |
* | |
* @param string $method Method name. | |
* @param integer $visibility Visibility (1 for public, 2 for public and | |
* protected, and 3 for all visibility) | |
* @return bool | |
*/ | |
public function respondsTo($method, $visibility = 0) { | |
return isset($this->_magicMethods[$method]) || parent::respondsTo($method, $visibility); | |
} | |
} | |
$foobar = new foobar(); | |
var_dump( | |
$foobar->respondsTo('foo'), // true | |
$foobar->respondsTo('bar'), // true | |
$foobar->respondsTo('baz'), // true | |
$foobar->respondsTo('foobaz'), // false | |
$foobar->respondsTo('foobaz', 1) // true | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It might be faster to do
ReflectionClass::getMethod
instead and do visibility checks after, but I'll benchmark before submitting a pr if this is desired functionality.