/** * Determines if the method is suitable to be used by the processor. * (see \Magento\Framework\Reflection\MethodsMap::isSuitableMethod) * * @param \ReflectionMethod $method * @return bool */ public function _isSuitableMethod(\ReflectionMethod $method) { /* '&&' usage is shorter then '||', if first part is 'false' then all equity is false */ $isSuitableMethodType = !$method->isStatic() && !$method->isFinal() && !$method->isConstructor() && !$method->isDestructor(); $isExcludedMagicMethod = strpos($method->getName(), '__') === 0; $result = $isSuitableMethodType && !$isExcludedMagicMethod; return $result; }
/** * Returns whether this method is a destructor * * @return boolean TRUE if this method is a destructor */ public function isDestructor() { if ($this->reflectionSource instanceof ReflectionMethod) { return $this->reflectionSource->isDestructor(); } else { return parent::isDestructor(); } }
/** * @inheritdoc */ public function condition(\ReflectionMethod $method) { if ($method->isPublic() && !($method->isAbstract() || $method->isConstructor() || $method->isDestructor())) { if ($this->isTest || strlen($method->name) > 4 && substr($method->name, 0, 4) === 'test') { return true; } } return false; }
/** * Load and run a test. * * @param string $name Name of test to run. This test should be located in {package}/tests * folder. * * @return NULL */ public function run($name) { // Ready the report. $report = new View_Component('test-result'); $report->outcome = 'pass'; $report->passes = 0; $report->fails = 0; $report->test_count = 0; $results = array(); // Load test. $test = ucfirst(strtolower($name)) . '_Test'; $report->test = $test; $reflector = new ReflectionClass($test); // Is it enabled? $constants = $reflector->getConstants(); if ($constants['ENABLED'] === TRUE) { $report->status = 'Enabled'; // Get the public methods, they are our tests. $public_methods = $reflector->getMethods(ReflectionMethod::IS_PUBLIC); $runnable = array(); foreach ($public_methods as $public_method) { $method = new ReflectionMethod($test, $public_method->name); // Constructor and Destructor should be used for setup/teardown only. if (!$method->isConstructor() && !$method->isDestructor()) { $runnable[] = $method; } } // Run each test. $report->test_count = count($runnable); foreach ($runnable as $run) { $result = new stdClass(); $result->test = $run->name; // Expectations will trigger Exceptions on failure. try { $run->invoke(new $test()); $result->outcome = 'pass'; $report->passes++; } catch (Exception $e) { $report->fails++; $report->outcome = 'fail'; $result->outcome = 'fail'; $result->error = $e->getMessage(); } array_push($results, $result); } } else { $report->status = 'Disabled'; } $report->results = $results; $report->display_content(); }
public function JResponse() { $result = null; if ($this->doAuthenticate()) { $mn = filter_input(INPUT_GET,self::$methodName,FILTER_SANITIZE_STRING); if (($mn!=null) && ($mn!=false)) { if (method_exists($this, $mn)) { $rfm = new ReflectionMethod($this, $mn); if (( $rfm->isPublic() ) && (!$rfm->isConstructor() ) && (!$rfm->isDestructor() )) { $result = call_user_func(array($this, $mn)); $this->doResponse($result); } else $this->doError("Method is not callable"); } else $this->doError("Method dose not exist"); } else $this->doError("Method must be specified"); } else $this->doError("Unauthorized"); }
/** * This method prevents catchable fatal errors when calling the API with missing arguments * @param string $method * @param array $arguments */ protected function validateCall($controller, $method, $arguments) { if (get_class($controller) == 'vB_Api_Null') { /* No such Class in the core controllers but it may be defined in an extension */ return 0; } if (method_exists($controller, $method)) { $reflection = new ReflectionMethod($controller, $method); } else { /* No such Method in the core controller but it may be defined in an extension */ return 0; } if ($reflection->isStatic()) { return 2; } if ($reflection->isConstructor()) { return 3; } if ($reflection->isDestructor()) { return 4; } $index = 0; foreach ($reflection->getParameters() as $param) { if (!isset($arguments[$index])) { if (!$param->allowsNull() and !$param->isDefaultValueAvailable()) { // cannot omit parameter throw new vB_Exception_Api('invalid_data'); } } else { if ($param->isArray() and !is_array($arguments[$index])) { // array type was expected throw new vB_Exception_Api('invalid_data'); } } $index++; } return 1; }
public function response() { parent::response(); $this->setError("", 0); $mn = $this->method; if (method_exists($this, $mn)) { $rfm = new ReflectionMethod($this, $mn); if (( $rfm->isPublic() ) && (!$rfm->isConstructor() ) && (!$rfm->isDestructor() ) && ( $mn != "response" ) && ( $mn != "isError" ) && ($mn != "setOperation") && ( $mn != "getError" ) && ( $mn != "getErrorCode" ) ) { $response = call_user_func(array($this, $mn)); return $response; } else { $this->setError("Method Access Problem", 2002); return false; } } else { $this->setError("Method not found", 2001); return false; } }
function reflectMethod($class, $method) { $methodInfo = new ReflectionMethod($class, $method); echo "**********************************\n"; echo "Reflecting on method {$class}::{$method}()\n\n"; echo "\nisFinal():\n"; var_dump($methodInfo->isFinal()); echo "\nisAbstract():\n"; var_dump($methodInfo->isAbstract()); echo "\nisPublic():\n"; var_dump($methodInfo->isPublic()); echo "\nisPrivate():\n"; var_dump($methodInfo->isPrivate()); echo "\nisProtected():\n"; var_dump($methodInfo->isProtected()); echo "\nisStatic():\n"; var_dump($methodInfo->isStatic()); echo "\nisConstructor():\n"; var_dump($methodInfo->isConstructor()); echo "\nisDestructor():\n"; var_dump($methodInfo->isDestructor()); echo "\n**********************************\n"; }
<?php trait Test { public function __construct() { } public function __destruct() { } public function func() { } } $rconstr = new ReflectionMethod('Test::__construct'); $rdestr = new ReflectionMethod('Test::__destruct'); $rfunc = new ReflectionMethod('Test::func'); var_dump($rconstr->isConstructor()); var_dump($rconstr->isDestructor()); var_dump($rdestr->isConstructor()); var_dump($rdestr->isDestructor()); var_dump($rfunc->isConstructor()); var_dump($rfunc->isDestructor());
/** * Check if the specified method should be used during generation builder generation. * * @param \ReflectionMethod $method * @return bool */ protected function canUseMethodForGeneration($method) { $isGetter = substr($method->getName(), 0, 3) == 'get' || substr($method->getName(), 0, 2) == 'is'; $isSuitableMethodType = !($method->isConstructor() || $method->isFinal() || $method->isStatic() || $method->isDestructor()); $isMagicMethod = in_array($method->getName(), ['__sleep', '__wakeup', '__clone']); $isPartOfExtensibleInterface = in_array($method->getName(), $this->getExtensibleInterfaceMethods()); return $isGetter && $isSuitableMethodType && !$isMagicMethod && !$isPartOfExtensibleInterface; }
/** * This will return a full proxy-method source. * * @param \ReflectionMethod $method The method to be proxied. * * @see Proxy::$methodTemplate * * @return string */ protected function createMethod(\ReflectionMethod $method) { $visibility = ''; $additional = ''; $name = $method->getName(); if ($method->isPublic()) { $visibility = ' public'; } else { if ($method->isProtected()) { $visibility = ' protected'; } else { if ($method->isPrivate()) { // useless really. $visibility = ' private'; return ''; } } } if ($method->isStatic()) { // useless really. $additional .= ' static '; return ''; } //if ($method->isAbstract()) { // useless really. $$additional .= ' abstract '; //return ''; //} if ($method->isConstructor()) { $name = '__construct'; } else { if ($method->isDestructor()) { $name = '__destruct'; } } $args = array(); foreach ($method->getParameters() as $parameter) { $args[] = $this->createParameter($parameter); } $src = $this->methodTemplate; $src = str_replace('VISIBILITY', $visibility, $src); $src = str_replace('ADDITIONAL', $additional, $src); $src = str_replace('METHOD_NAME', $name, $src); $src = str_replace('METHOD_ARGS', implode(',', $args), $src); $src = str_replace('CLASS_NAME', $method->getDeclaringClass()->getName(), $src); return $src; }
} catch (TypeError $re) { echo "Ok - " . $re->getMessage() . PHP_EOL; } try { new ReflectionMethod('a', 'b', 'c'); } catch (TypeError $re) { echo "Ok - " . $re->getMessage() . PHP_EOL; } class C { public function f() { } } $rm = new ReflectionMethod('C', 'f'); var_dump($rm->isFinal(1)); var_dump($rm->isAbstract(1)); var_dump($rm->isPrivate(1)); var_dump($rm->isProtected(1)); var_dump($rm->isPublic(1)); var_dump($rm->isStatic(1)); var_dump($rm->isConstructor(1)); var_dump($rm->isDestructor(1)); var_dump($rm->getModifiers(1)); var_dump($rm->isInternal(1)); var_dump($rm->isUserDefined(1)); var_dump($rm->getFileName(1)); var_dump($rm->getStartLine(1)); var_dump($rm->getEndLine(1)); var_dump($rm->getStaticVariables(1)); var_dump($rm->getName(1));
/** * Extract method information using PHP reflection. * * Options may include: * - include: List of properties to return * - exclude: List of properties to not return * * @param ReflectionMethod $method * @return array * * @param ReflectionMethod $method * @param array $options [optional] * @return array * * @param string $class * @param string $method * @return array * * @param string $class * @param string $method * @param array $options [optional] * @return array */ public static function method(){ $args = func_get_args(); switch(count($args)){ case 1: $reflection = $args[0]; break; case 2: if($args[0] instanceof ReflectionMethod){ $reflection = $args[0]; $options = $args[1]; }else{ $reflection = new ReflectionMethod($args[0],$args[1]); } break; case 3: $reflection = new ReflectionMethod($args[0],$args[1]); $options = $args[2]; break; default: throw new InvalidArgumentException('Invalid argument count'); } // Sanitize option "include" if(isset($options['include'])){ if(is_string($options['include'])){ $options['include'] = explode(',',$options['include']); } if(is_array($options['include'])){ $includeKeys = array(); foreach($options['include'] as $key=>$value){ if(is_int($key)){ $includeKeys[$value] = true; }else if(is_array($value)){ $includeKeys[$key] = $value; } } }else{ $includeKeys = false; } }else{ $includeKeys = false; } // Sanitize option "exclude" if(!empty($options['exclude'])){ if(is_string($options['exclude'])){ $options['exclude'] = explode(',',$options['exclude']); } if(is_array($options['exclude'])){ $excludeKeys = array(); foreach($options['exclude'] as $key=>$value){ if(is_int($key)){ $excludeKeys[$value] = true; }else if(is_array($value)){ $excludeKeys[$key] = $value; } } }else{ $excludeKeys = false; } }else{ $excludeKeys = false; } $keys = array( 'name', 'filename', 'is_abstract', 'is_constructor', 'is_destructor', 'is_final', 'is_private', 'is_protected', 'is_public', 'is_static', 'comment', 'summary', 'attributes'); foreach($keys as $key){ $options['return_'.$key] = !($excludeKeys && !empty($excludeKeys[$key]) && !is_array($excludeKeys[$key]))&&!($includeKeys && empty($includeKeys[$key])); } // Prepare returned array $return = array(); // Start reflection if($options['return_name']){ $return['name'] = $reflection->getName(); } if($options['return_filename']){ $return['filename'] = $reflection->getFileName(); } if($options['return_is_abstract']){ $return['is_abstract'] = $reflection->isAbstract(); } if($options['return_is_constructor']){ $return['is_constructor'] = $reflection->isConstructor(); } if($options['return_is_destructor']){ $return['is_destructor'] = $reflection->isDestructor(); } if($options['return_is_final']){ $return['is_final'] = $reflection->isFinal(); } if($options['return_is_private']){ $return['is_private'] = $reflection->isPrivate(); } if($options['return_is_protected']){ $return['is_protected'] = $reflection->isProtected(); } if($options['return_is_public']){ $return['is_public'] = $reflection->isPublic(); } if($options['return_is_static']){ $return['is_static'] = $reflection->isStatic(); } list($comment,$summary,$attributes) = self::comment($reflection); if($options['return_comment']){ $return['comment'] = $comment; } if($options['return_summary']){ $return['summary'] = $summary; } if($options['return_attributes']){ $return['attributes'] = $attributes; } return $return; }
/** * Whether method is intercepted * * @param \ReflectionMethod $method * @return bool */ protected function isInterceptedMethod(\ReflectionMethod $method) { return !($method->isConstructor() || $method->isFinal() || $method->isStatic() || $method->isDestructor()) && !in_array($method->getName(), ['__sleep', '__wakeup', '__clone']); }
/** * Given a user-defined PHP class or php object, map its methods onto a list of * PHP 'wrapper' functions that can be exposed as xmlrpc methods from an xmlrpc server * object and called from remote clients (as well as their corresponding signature info). * * @param string|object $className the name of the class whose methods are to be exposed as xmlrpc methods, or an object instance of that class * @param array $extraOptions see the docs for wrapPhpMethod for basic options, plus * - string method_type 'static', 'nonstatic', 'all' and 'auto' (default); the latter will switch between static and non-static depending on whether $className is a class name or object instance * - string method_filter a regexp used to filter methods to wrap based on their names * - string prefix used for the names of the xmlrpc methods created * * @return array|false false on failure */ public function wrapPhpClass($className, $extraOptions = array()) { $methodFilter = isset($extraOptions['method_filter']) ? $extraOptions['method_filter'] : ''; $methodType = isset($extraOptions['method_type']) ? $extraOptions['method_type'] : 'auto'; $prefix = isset($extraOptions['prefix']) ? $extraOptions['prefix'] : ''; $results = array(); $mList = get_class_methods($className); foreach ($mList as $mName) { if ($methodFilter == '' || preg_match($methodFilter, $mName)) { $func = new \ReflectionMethod($className, $mName); if (!$func->isPrivate() && !$func->isProtected() && !$func->isConstructor() && !$func->isDestructor() && !$func->isAbstract()) { if ($func->isStatic() && ($methodType == 'all' || $methodType == 'static' || $methodType == 'auto' && is_string($className)) || !$func->isStatic() && ($methodType == 'all' || $methodType == 'nonstatic' || $methodType == 'auto' && is_object($className))) { $methodWrap = $this->wrapPhpFunction(array($className, $mName), '', $extraOptions); if ($methodWrap) { if (is_object($className)) { $realClassName = get_class($className); } else { $realClassName = $className; } $results[$prefix . "{$realClassName}.{$mName}"] = $methodWrap; } } } } } return $results; }
$right = strrpos($value, '.'); $left = strlen($dir) + 1; $name = substr($value, $left, $right - $left); if (stristr($name, 'Service')) { $tokens = split('_', $name); $str = ''; foreach ($tokens as $t => $token) { $str = $str . strtoupper(substr($token, 0, 1)) . substr($token, 1); } if ($str != '') { require_once $value; $instance = new $str(); $methods = get_class_methods($instance); foreach ($methods as $m => $method) { $rm = new ReflectionMethod($str, $method); if ($rm->isUserDefined() && !$rm->isConstructor() && !$rm->isDestructor() && $rm->getNumberOfParameters() == 2) { $comment = $rm->getDocComment(); $metadata = getServiceMetadata($comment); if ($metadata === FALSE) { // could not parse metadata continue; } $request = $metadata['request']; $adapter = new ServiceAdapter($instance, $rm, $metadata); registerService($request, $adapter, $services); } } } } } function getRequests($content_type, $input)
/** * Ajax calls to /ajax/call/[controller]/[method] allow calling a * presentation controller * * @param string API controller * @param string API method * * @param mixed The return value of the API call */ public function actionCall($controller, $method) { if (!empty($controller)) { $args = array_merge($_GET, $_POST); $class = 'vB5_Frontend_Controller_' . ucfirst($controller); // TODO: This is a temporary fix for VBV-4731. Only 'action' methods can be called from ajax/call if (strpos($method, 'action') !== 0) { $method = 'action' . $method; } if (!class_exists($class) || !method_exists($class, $method)) { return null; } else { $object = new $class(); } $reflection = new ReflectionMethod($object, $method); if ($reflection->isConstructor() || $reflection->isDestructor() || $reflection->isStatic()) { return null; } $php_args = array(); foreach ($reflection->getParameters() as $param) { if (isset($args[$param->getName()])) { $php_args[] =& $args[$param->getName()]; } else { if ($param->isDefaultValueAvailable()) { $php_args[] = $param->getDefaultValue(); } else { throw new Exception('Required argument missing: ' . htmlspecialchars($param->getName())); return null; } } } return $reflection->invokeArgs($object, $php_args); } return null; }
/** * Given a user-defined PHP class or php object, map its methods onto a list of * PHP 'wrapper' functions that can be exposed as xmlrpc methods from an xmlrpc_server * object and called from remote clients (as well as their corresponding signature info). * * @param mixed $classname the name of the class whose methods are to be exposed as xmlrpc methods, or an object instance of that class * @param array $extra_options see the docs for wrap_php_method for more options * string method_type 'static', 'nonstatic', 'all' and 'auto' (default); the latter will switch between static and non-static depending on wheter $classname is a class name or object instance * @return array or false on failure * * @todo get_class_methods will return both static and non-static methods. * we have to differentiate the action, depending on wheter we recived a class name or object */ function wrap_php_class($classname, $extra_options = array()) { $methodfilter = isset($extra_options['method_filter']) ? $extra_options['method_filter'] : ''; $methodtype = isset($extra_options['method_type']) ? $extra_options['method_type'] : 'auto'; if (version_compare(phpversion(), '5.0.3') == -1) { // up to php 5.0.3 some useful reflection methods were missing error_log('XML-RPC: cannot not wrap php functions unless running php version bigger than 5.0.3'); return false; } $result = array(); $mlist = get_class_methods($classname); foreach ($mlist as $mname) { if ($methodfilter == '' || preg_match($methodfilter, $mname)) { // echo $mlist."\n"; $func = new ReflectionMethod($classname, $mname); if (!$func->isPrivate() && !$func->isProtected() && !$func->isConstructor() && !$func->isDestructor() && !$func->isAbstract()) { if ($func->isStatic && ($methodtype == 'all' || $methodtype == 'static' || $methodtype == 'auto' && is_string($classname)) || !$func->isStatic && ($methodtype == 'all' || $methodtype == 'nonstatic' || $methodtype == 'auto' && is_object($classname))) { $methodwrap = wrap_php_function(array($classname, $mname), '', $extra_options); if ($methodwrap) { $result[$methodwrap['function']] = $methodwrap['function']; } } } } } return $result; }
/** * Call the given api function by name with a named arguments list. * Used primarily to translate REST requests into API calls. * * @param string $method -- the name of the method to call * @param array $args -- The list of args to call. This is a name => value map that will * be matched up to the names of the API method. Order is not important. The names are * case sensitive. * * @return The return of the method or an error if the method doesn't exist, or is * static, a constructor or destructor, or otherwise shouldn't be callable as * and API method. It is also an error if the value of a paramater is not provided * and that parameter doesn't have a default value. */ public function callNamed() { list($method, $args) = func_get_args(); if (!is_callable(array($this, $method))) { // if the method does not exist, an extension might define it return; } $reflection = new ReflectionMethod($this, $method); if ($reflection->isConstructor() || $reflection->isDestructor() || $reflection->isStatic() || $method == "callNamed") { //todo return error message return; } $php_args = array(); foreach ($reflection->getParameters() as $param) { // the param value can be null, so don't use isset if (array_key_exists($param->getName(), $args)) { $php_args[] =& $args[$param->getName()]; } else { if ($param->isDefaultValueAvailable()) { $php_args[] = $param->getDefaultValue(); } else { throw new Exception('Required argument missing: ' . htmlspecialchars($param->getName())); //todo: return error message return; } } } return $reflection->invokeArgs($this, $php_args); }
private function isMethodValid(\ReflectionMethod $method) { return !($method->isConstructor() || $method->isDestructor() || $method->isStatic() || $method->isFinal()); }
protected function canMockMethod(ReflectionMethod $method) { if ($method->isConstructor() || $method->isDestructor() || $method->isFinal() || $method->getName() == '__clone') { return FALSE; } return TRUE; }
/** * Determines if the method is suitable to be used by the processor. * * @param \ReflectionMethod $method * @return bool */ private function isSuitableMethod($method) { $isSuitableMethodType = !($method->isConstructor() || $method->isFinal() || $method->isStatic() || $method->isDestructor()); $isExcludedMagicMethod = strpos($method->getName(), '__') === 0; return $isSuitableMethodType && !$isExcludedMagicMethod; }
/** * 框架控制函数 * * @param array $array * @param array $return_array * @return mixed */ private static function _main_framework($array, $return_array) { // 1. 设置默认值、替换内置宏 list($classname_static, $debug_backtrace_file) = self::_main_framework_first(); if (empty($array['framework_require'])) { $require = ''; } else { $require = $array['framework_require']; if (strpos($require, '(self)') !== false) { $require = str_replace('(self)', __CLASS__, $require); } if (strpos($require, '(static)') !== false) { $require = str_replace('(static)', $classname_static, $require); } } if (empty($array['framework_module'])) { $module = $classname_static . '!' . __CLASS__; //默认值:(static)!(self) } else { $module = $array['framework_module']; if (strpos($module, '(self)') !== false) { $module = str_replace('(self)', __CLASS__, $module); } if (strpos($module, '(static)') !== false) { $module = str_replace('(static)', $classname_static, $module); } } if (empty($array['framework_action'])) { $action = '[get:1]|index'; //默认值:[get:1]|index } else { $action = $array['framework_action']; } $action_multi = is_array($action); if ($action_multi) { $action_array =& $action; $action_string = implode(' ', $action); } else { $action_array = array(&$action); $action_string = $action; } foreach ($action_array as &$action_value) { if (strpos($action_value, '(self)') !== false) { $action_value = str_replace('(self)', __CLASS__, $action_value); } if (strpos($action_value, '(static)') !== false) { $action_value = str_replace('(static)', $classname_static, $action_value); } } if (empty($array['framework_parameter'])) { $parameter = ''; } else { $parameter = $array['framework_parameter']; } $parameter_multi = is_array($parameter); if ($parameter_multi) { $parameter_array =& $parameter; $parameter_string = implode(' ', $parameter); } else { $parameter_array = array(&$parameter); $parameter_string = $parameter; } foreach ($parameter_array as &$parameter_value) { if (strpos($parameter_value, '(self)') !== false) { $parameter_value = str_replace('(self)', __CLASS__, $parameter_value); } if (strpos($parameter_value, '(static)') !== false) { $parameter_value = str_replace('(static)', $classname_static, $parameter_value); } } // 2. 生成替换数组 $value_array = array(); $string = $require . ' ' . $module . ' ' . $action_string . ' ' . $parameter_string; if (stripos($string, '[get:') !== false) { $get_array = array_values($_GET) + $_GET; array_unshift($get_array, null); $value_array['get'] = $get_array; } if (stripos($string, '[post:') !== false) { $post_array = array_values($_POST) + $_POST; array_unshift($post_array, null); $value_array['post'] = $post_array; } if (stripos($string, '[query:') !== false) { $query_array = array(); if (isset($_SERVER['QUERY_STRING'])) { $query_string = $_SERVER['QUERY_STRING']; $query_array = explode('&', $query_string); array_unshift($query_array, $query_string); } $value_array['query'] = $query_array; } if (stripos($string, '[path:') !== false) { $path_array = array(); if (isset($_SERVER['PATH_INFO'])) { $path_info = trim($_SERVER['PATH_INFO'], '/'); $path_array[] = $path_info; $tok = strtok($path_info, '/'); while ($tok !== false) { $path_array[] = $tok; $tok = strtok('/'); } } $path_array['path'] = $path_array; $value_array['path'] = $path_array; } if (stripos($string, '[file:') !== false) { $file_array = array(); if ($debug_backtrace_file === null) { list(, $row) = debug_backtrace(); $debug_backtrace_file = $row['file']; } strtok($debug_backtrace_file, '/\\'); while (($tok = strtok('/\\')) !== false) { array_unshift($file_array, $tok); } $file_array[0] = strtok($file_array[0], '.'); array_unshift($file_array, strtok('.')); $value_array['file'] = $file_array; } // 3. 生成返回数组 $return4_array = array_values(array_intersect($return_array, array('require', 'module', 'action', 'parameter'))); if (empty($return4_array)) { $return4_result = array(); $return4_final = ''; } else { $return4_result = array_flip($return4_array); if (isset($return4_result['require'])) { $return4_result['require'] = false; $return4_final = 'require'; } if (isset($return4_result['module'])) { $return4_result['module'] = false; $return4_final = 'module'; } if (isset($return4_result['action'])) { $return4_result['action'] = false; $return4_final = 'action'; } if (isset($return4_result['parameter'])) { $return4_result['parameter'] = false; $return4_final = 'parameter'; } } // 4. 处理引用部份 $require_now = ''; if ($require) { $result_array = self::_main_framework_resolve($require, $value_array, 'require'); foreach ($result_array as $value) { $value_file = self::_path_file($value); if (is_file($value_file)) { $require_now = $value; $require_name = $value_file; break; } } if ($require_now === '') { if ($return4_final === '') { if (!in_array('manual', $return_array)) { self::_main_hide($array); } return false; } elseif (count($return4_array) === 1) { return false; } else { return array_values($return4_result); } } require_once $require_name; } if (isset($return4_result['require'])) { $return4_result['require'] = $require_now; } if ($return4_array === array('require')) { return $require_now; } elseif ($return4_final === 'require') { return array_values($return4_result); } // 5. 处理模块部份 $module_now = ''; $result_array = self::_main_framework_resolve($module, $value_array, 'module'); foreach ($result_array as $value) { if (preg_match('/(^|\\\\)[0-9]/', $value) === 1) { continue; } try { if (!class_exists($value)) { continue; } } catch (Exception $e) { continue; } $class = new ReflectionClass($value); if ($class->isInternal() || $class->isAbstract() || $class->isInterface()) { continue; } $module_now = $value; break; } if ($module_now === '') { if ($return4_final === '') { if (!in_array('manual', $return_array)) { self::_main_hide($array); } return false; } elseif (count($return4_array) === 1) { return false; } else { return array_values($return4_result); } } else { if (isset($return4_result['module'])) { $return4_result['module'] = $module_now; } if ($return4_array === array('module')) { return $module_now; } elseif ($return4_final === 'module') { return array_values($return4_result); } } // 6. 处理动作部份 if ($action_multi) { $action_now = array(); } else { $action_now = false; } foreach ($action_array as $action_key => &$action_value) { $action_now2 = false; $action_extra = strncmp($action_value, '*|', 2) === 0; if ($action_extra) { $action_value2 = substr($action_value, 2); $action_now2 = ''; } else { $action_value2 = $action_value; } $result_array = self::_main_framework_resolve($action_value2, $value_array, 'action', $module_now); foreach ($result_array as $value) { list($module_new, $action_new) = $value; if ($module_new === '(function)') { if (!function_exists($action_new)) { continue; } $module_now2 = ''; $action_now2 = $action_new; break; } else { if ($module_new !== $module_now) { if (preg_match('/(^|\\\\)[0-9]/', $module_new) === 1) { continue; } try { if (!class_exists($module_new)) { continue; } } catch (Exception $e) { continue; } $class = new ReflectionClass($module_new); if ($class->isAbstract() || $class->isInterface()) { continue; } if (!$action_extra && $class->isInternal()) { continue; } } if (!method_exists($module_new, $action_new)) { continue; } $method = new ReflectionMethod($module_new, $action_new); if (!$method->isPublic() || $method->isConstructor() || $method->isDestructor()) { continue; } if (!$action_extra && in_array('static', $return_array) && !in_array('object', $return_array)) { if (!$method->isStatic()) { continue; } } elseif (!$action_extra && in_array('object', $return_array) && !in_array('static', $return_array)) { if ($method->isStatic()) { continue; } } if (!$action_extra && in_array('final', $return_array)) { if (!$method->isFinal()) { continue; } } $module_now2 = $method->isStatic() ? $module_new : new $module_new(); $action_now2 = $action_new; break; } } if ($action_now2 === false) { if (!$action_extra) { if ($action_multi) { $action_now = array(); } else { $action_now = false; } break; } } elseif ($action_now2 === '') { if ($action_multi) { $action_now[$action_key] = ''; } else { $action_now = ''; } } else { if ($action_multi) { if ($module_now2 === '') { $action_now[$action_key] = $action_now2; } else { $action_now[$action_key] = array($module_now2, $action_now2); } } else { $module_now = $module_now2; $action_now = $action_now2; if (isset($return4_result['module'])) { $return4_result['module'] = $module_now; } } } } if ($action_now === false || $action === array()) { if ($return4_final === '') { if (!in_array('manual', $return_array)) { self::_main_hide($array); } return false; } elseif (count($return4_array) === 1) { return false; } else { return array_values($return4_result); } } else { if (isset($return4_result['action'])) { $return4_result['action'] = $action_now; } if ($return4_array === array('action')) { return $action_now; } elseif ($return4_final === 'action') { return array_values($return4_result); } } // 7. 处理参数部份 $parameter_now = array(); if ($action_multi) { foreach ($action_now as $action_key => &$action_value) { $parameter_now[$action_key] = array(); if ($parameter && is_array($parameter) && isset($parameter[$action_key]) && $action_value !== '') { if (!is_array($action_value)) { $module_now3 = ''; $action_now3 = $action_value; } elseif (is_object($action_value[0])) { $module_now3 = get_class($action_value[0]); $action_now3 = $action_value[1]; } else { $module_now3 = $action_value[0]; $action_now3 = $action_value[1]; } $result_array = self::_main_framework_resolve($parameter[$action_key], $value_array, 'parameter', array($module_now3, $action_now3)); foreach ($result_array as $value) { $parameter_now[$action_key] = array_slice($value, 2); break; } } } } else { if ($parameter && $action_now !== '') { $module_now3 = is_object($module_now) ? get_class($module_now) : $module_now; $action_now3 = $action_now; $result_array = self::_main_framework_resolve($parameter, $value_array, 'parameter', array($module_now3, $action_now3)); foreach ($result_array as $value) { $parameter_now = array_slice($value, 2); break; } } } if (isset($return4_result['parameter'])) { $return4_result['parameter'] = $parameter_now; } if ($return4_array === array('parameter')) { return $parameter_now; } elseif ($return4_final === 'parameter') { return array_values($return4_result); } // 8. 执行 if ($action_multi) { $return = array(); foreach ($action_now as $action_key => &$action_value) { if ($action_value === '') { $return[$action_key] = null; } elseif ($action_value[0] === '') { $return[$action_key] = call_user_func_array($action_value[1], $parameter_now[$action_key]); } else { $return[$action_key] = call_user_func_array($action_value, $parameter_now[$action_key]); } } } else { if ($action_now === '') { $return = null; } elseif ($module_now === '') { $return = call_user_func_array($action_now, $parameter_now); } else { $return = call_user_func_array(array($module_now, $action_now), $parameter_now); } } if (in_array('return', $return_array)) { return $return; } else { return true; } }
/** * @param ReflectionMethod $method * @return bool */ function isOverridableMethod(ReflectionMethod $method) { return !($method->isStatic() || $method->isFinal() || !$method->isPublic() || $method->isConstructor() || $method->isDestructor() || in_array($method->getName(), array('__clone'))); }
private static function getDeclaredOnlyInstanceMethods($class) { $methods = self::getDeclaredOnlyMethods($class); $instanceMethods = array(); foreach ($methods as $name) { $method = new ReflectionMethod($class, $name); if ($method->isPublic() && !$method->isStatic() && !$method->isConstructor() && !$method->isDestructor() && !$method->isAbstract()) { $instanceMethods[] = $name; } } if (empty($instanceMethods)) { throw new Exception('There is no pubic instance method in class $class.'); } return $instanceMethods; }