reflection_php5.php.svn-base

来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· SVN-BASE 代码 · 共 381 行

SVN-BASE
381
字号
<?php/** *  base include file for SimpleTest *  @package    SimpleTest *  @subpackage UnitTester *  @version    $Id: reflection_php5.php 1683 2008-03-05 21:57:08Z lastcraft $ *//** *    Version specific reflection API. *    @package SimpleTest *    @subpackage UnitTester */class SimpleReflection {    var $_interface;    /**     *    Stashes the class/interface.     *    @param string $interface    Class or interface     *                                to inspect.     */    function SimpleReflection($interface) {        $this->_interface = $interface;    }    /**     *    Checks that a class has been declared. Versions     *    before PHP5.0.2 need a check that it's not really     *    an interface.     *    @return boolean            True if defined.     *    @access public     */    function classExists() {        if (! class_exists($this->_interface)) {            return false;        }        $reflection = new ReflectionClass($this->_interface);        return ! $reflection->isInterface();    }    /**     *    Needed to kill the autoload feature in PHP5     *    for classes created dynamically.     *    @return boolean        True if defined.     *    @access public     */    function classExistsSansAutoload() {        return class_exists($this->_interface, false);    }    /**     *    Checks that a class or interface has been     *    declared.     *    @return boolean            True if defined.     *    @access public     */    function classOrInterfaceExists() {        return $this->_classOrInterfaceExistsWithAutoload($this->_interface, true);    }    /**     *    Needed to kill the autoload feature in PHP5     *    for classes created dynamically.     *    @return boolean        True if defined.     *    @access public     */    function classOrInterfaceExistsSansAutoload() {        return $this->_classOrInterfaceExistsWithAutoload($this->_interface, false);    }    /**     *    Needed to select the autoload feature in PHP5     *    for classes created dynamically.     *    @param string $interface       Class or interface name.     *    @param boolean $autoload       True totriggerautoload.     *    @return boolean                True if interface defined.     *    @access private     */    function _classOrInterfaceExistsWithAutoload($interface, $autoload) {        if (function_exists('interface_exists')) {            if (interface_exists($this->_interface, $autoload)) {                return true;            }        }        return class_exists($this->_interface, $autoload);    }    /**     *    Gets the list of methods on a class or     *    interface.     *    @returns array              List of method names.     *    @access public     */    function getMethods() {        return array_unique(get_class_methods($this->_interface));    }    /**     *    Gets the list of interfaces from a class. If the     *    class name is actually an interface then just that     *    interface is returned.     *    @returns array          List of interfaces.     *    @access public     */    function getInterfaces() {        $reflection = new ReflectionClass($this->_interface);        if ($reflection->isInterface()) {            return array($this->_interface);        }        return $this->_onlyParents($reflection->getInterfaces());    }    /**     *    Gets the list of methods for the implemented     *    interfaces only.     *    @returns array      List of enforced method signatures.     *    @access public     */    function getInterfaceMethods() {        $methods = array();        foreach ($this->getInterfaces() as $interface) {            $methods = array_merge($methods, get_class_methods($interface));        }        return array_unique($methods);    }    /**     *    Checks to see if the method signature has to be tightly     *    specified.     *    @param string $method        Method name.     *    @returns boolean             True if enforced.     *    @access private     */    function _isInterfaceMethod($method) {        return in_array($method, $this->getInterfaceMethods());    }    /**     *    Finds the parent class name.     *    @returns string      Parent class name.     *    @access public     */    function getParent() {        $reflection = new ReflectionClass($this->_interface);        $parent = $reflection->getParentClass();        if ($parent) {            return $parent->getName();        }        return false;    }    /**     *    Trivially determines if the class is abstract.     *    @returns boolean      True if abstract.     *    @access public     */    function isAbstract() {        $reflection = new ReflectionClass($this->_interface);        return $reflection->isAbstract();    }    /**     *    Trivially determines if the class is an interface.     *    @returns boolean      True if interface.     *    @access public     */    function isInterface() {        $reflection = new ReflectionClass($this->_interface);        return $reflection->isInterface();    }    /**     *    Scans for final methods, as they screw up inherited     *    mocks by not allowing you to override them.     *    @returns boolean   True if the class has a final method.     *    @access public     */    function hasFinal() {        $reflection = new ReflectionClass($this->_interface);        foreach ($reflection->getMethods() as $method) {            if ($method->isFinal()) {                return true;            }        }        return false;    }    /**     *    Whittles a list of interfaces down to only the     *    necessary top level parents.     *    @param array $interfaces     Reflection API interfaces     *                                 to reduce.     *    @returns array               List of parent interface names.     *    @access private     */    function _onlyParents($interfaces) {        $parents = array();        $blacklist = array();        foreach ($interfaces as $interface) {            foreach($interfaces as $possible_parent) {                if ($interface->getName() == $possible_parent->getName()) {                    continue;                }                if ($interface->isSubClassOf($possible_parent)) {                    $blacklist[$possible_parent->getName()] = true;                }            }            if (!isset($blacklist[$interface->getName()])) {                $parents[] = $interface->getName();            }        }        return $parents;    }    /**     * Checks whether a method is abstract or not.     * @param   string   $name  Method name.     * @return  bool            true if method is abstract, else false     * @access  private     */    function _isAbstractMethod($name) {        $interface = new ReflectionClass($this->_interface);        if (! $interface->hasMethod($name)) {            return false;        }        return $interface->getMethod($name)->isAbstract();    }    /**     * Checks whether a method is the constructor.     * @param   string   $name  Method name.     * @return  bool            true if method is the constructor     * @access  private     */    function _isConstructor($name) {        return ($name == '__construct') || ($name == $this->_interface);    }    /**     * Checks whether a method is abstract in all parents or not.     * @param   string   $name  Method name.     * @return  bool            true if method is abstract in parent, else false     * @access  private     */    function _isAbstractMethodInParents($name) {        $interface = new ReflectionClass($this->_interface);        $parent = $interface->getParentClass();        while($parent) {            if (! $parent->hasMethod($name)) {                return false;            }            if ($parent->getMethod($name)->isAbstract()) {                return true;            }            $parent = $parent->getParentClass();        }        return false;    }    /**     * Checks whether a method is static or not.     * @param   string  $name   Method name     * @return  bool            true if method is static, else false     * @access  private     */    function _isStaticMethod($name) {        $interface = new ReflectionClass($this->_interface);        if (! $interface->hasMethod($name)) {            return false;        }        return $interface->getMethod($name)->isStatic();    }    /**     *    Writes the source code matching the declaration     *    of a method.     *    @param string $name    Method name.     *    @return string         Method signature up to last     *                           bracket.     *    @access public     */    function getSignature($name) {        if ($name == '__set') {            return 'function __set($key, $value)';        }        if ($name == '__call') {            return 'function __call($method, $arguments)';        }        if (version_compare(phpversion(), '5.1.0', '>=')) {            if (in_array($name, array('__get', '__isset', $name == '__unset'))) {                return "function {$name}(\$key)";            }        }        if ($name == '__toString') {            return "function $name()";        }        if ($this->_isInterfaceMethod($name) ||                $this->_isAbstractMethod($name) ||                $this->_isAbstractMethodInParents($name) ||                $this->_isStaticMethod($name)) {            return $this->_getFullSignature($name);        }        return "function $name()";    }    /**     *    For a signature specified in an interface, full     *    details must be replicated to be a valid implementation.     *    @param string $name    Method name.     *    @return string         Method signature up to last     *                           bracket.     *    @access private     */    function _getFullSignature($name) {        $interface = new ReflectionClass($this->_interface);        $method = $interface->getMethod($name);        $reference = $method->returnsReference() ? '&' : '';        $static = $method->isStatic() ? 'static ' : '';        return "{$static}function $reference$name(" .                implode(', ', $this->_getParameterSignatures($method)) .                ")";    }    /**     *    Gets the source code for each parameter.     *    @param ReflectionMethod $method   Method object from     *                                      reflection API     *    @return array                     List of strings, each     *                                      a snippet of code.     *    @access private     */    function _getParameterSignatures($method) {        $signatures = array();        foreach ($method->getParameters() as $parameter) {            $signature = '';            $type = $parameter->getClass();            if (is_null($type) && version_compare(phpversion(), '5.1.0', '>=') && $parameter->isArray()) {                $signature .= 'array ';            } elseif (!is_null($type)) {                $signature .= $type->getName() . ' ';            }            if ($parameter->isPassedByReference()) {                $signature .= '&';            }            $signature .= '$' . $this->_suppressSpurious($parameter->getName());            if ($this->_isOptional($parameter)) {                $signature .= ' = null';            }            $signatures[] = $signature;        }        return $signatures;    }    /**     *    The SPL library has problems with the     *    Reflection library. In particular, you can     *    get extra characters in parameter names :(.     *    @param string $name    Parameter name.     *    @return string         Cleaner name.     *    @access private     */    function _suppressSpurious($name) {        return str_replace(array('[', ']', ' '), '', $name);    }    /**     *    Test of a reflection parameter being optional     *    that works with early versions of PHP5.     *    @param reflectionParameter $parameter    Is this optional.     *    @return boolean                          True if optional.     *    @access private     */    function _isOptional($parameter) {        if (method_exists($parameter, 'isOptional')) {            return $parameter->isOptional();        }        return false;    }}?>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?