typeAdapter = new TypeAdapter(); } /** * @param mixed $object * @param string $method * @param array $parameters * * @return mixed */ public function invoke($object, string $method, array $parameters) { $handler = $object; $reflection = new \ReflectionMethod($handler, $method); if ($reflection->getNumberOfRequiredParameters() > count($parameters)) { throw new InvalidParamsException('Expected ' . $reflection->getNumberOfRequiredParameters() . ' parameters'); } $formalParameters = $reflection->getParameters(); $actualParameters = $this->prepareActualParameters($formalParameters, $parameters); try { $result = $reflection->invokeArgs($handler, $actualParameters); } catch (\Exception $exception) { throw new ServerErrorException($exception->getMessage(), $exception->getCode()); } return $this->castResult($result); } /** * @return TypeAdapter */ public function getTypeAdapter(): TypeAdapter { return $this->typeAdapter; } /** * @param \ReflectionParameter[] $formalParameters Formal parameters * @param array $parameters Parameters from request (raw) * * @return array */ private function prepareActualParameters(array $formalParameters, array $parameters): array { $result = []; // Handle named parameters if ($this->isNamedArray($parameters)) { foreach ($formalParameters as $formalParameter) { /** @var \ReflectionParameter $formalParameter */ $formalType = (string) $formalParameter->getType(); $name = $formalParameter->name; if ($formalParameter->isOptional()) { if (!array_key_exists($name, $parameters)) { $result[$name] = $formalParameter->getDefaultValue(); continue; } if ($formalParameter->allowsNull() && $parameters[$name] === null) { $result[$name] = $parameters[$name]; continue; } $result[$name] = $formalParameter->getClass() !== null ? $this->toObject($formalParameter->getClass()->name, $parameters[$name]) : $this->matchType($formalType, $parameters[$name]); } if (!array_key_exists($name, $parameters)) { throw new InvalidParamsException('Named parameter error'); } $result[$name] = $this->matchType($formalType, $parameters[$name]); } return $result; } // Handle positional parameters foreach ($formalParameters as $position => $formalParameter) { /** @var \ReflectionParameter $formalParameter */ if ($formalParameter->isOptional() && !isset($parameters[$position])) { break; } if (!isset($parameters[$position])) { throw new InvalidParamsException('Positional parameter error'); } $formalType = (string) $formalParameter->getType(); $result[] = $formalParameter->getClass() !== null ? $this->toObject($formalParameter->getClass()->name, $parameters[$position]) : $this->matchType($formalType, $parameters[$position]); } return $result; } /** * @param array $rawParameters * * @return bool */ private function isNamedArray(array $rawParameters): bool { return array_keys($rawParameters) !== range(0, count($rawParameters) - 1); } /** * @param string $formalType * @param mixed $value * * @return mixed */ private function matchType(string $formalType, $value) { // Parameter without type-hinting returns as is if ($formalType === '') { return $value; } if ($this->isType($formalType, $value)) { return $value; } throw new InvalidParamsException('Type hint failed'); } /** * @param string $formalClass * @param mixed $value * * @return mixed */ private function toObject(string $formalClass, $value) { if ($this->typeAdapter->isClassRegistered($formalClass)) { try { return $this->typeAdapter->toObject($value); } catch (TypeCastException $exception) { throw new InvalidParamsException('Class cast failed'); } } throw new InvalidParamsException('Class hint failed'); } /** * @param string $type * @param $value * * @return bool */ private function isType(string $type, $value) { switch ($type) { case 'bool': return is_bool($value); case 'int': return is_int($value); case 'float': return is_float($value) || is_int($value); case 'string': return is_string($value); case 'array': return is_array($value); default: throw new InvalidParamsException('Type match error'); } } /** * @param $result * * @return mixed */ private function castResult($result) { try { $result = $this->typeAdapter->toArray($result); } catch (TypeCastException $exception) { return $result; } return $result; } } __halt_compiler();----SIGNATURE:----dZC6r1WVTv3ay8wxv8Ol+T7Hucbtl4yuN6dAfq7O6Ot70GVe8S4Tv8cU2UEdSDHyIYbwiwKnaIm86oLDTAvcLEIiYeTaIML/zDk4T1dukgkbAPhIJy/+lN4ZY8hb0X8giGVhY7z7ff20tJoYpa8Pj004OdyDWtrjHbygnduy2jv/Vsbher56UX/ZN0ESueg1CS2aze+DMUecGgzB53H+lnseDv0Ci8knAB6M3UeMFdcQcUqQaRbUbgySBsVFByHDSNTxuoTSHvLAIuHqAmGej1qONqvYu/iRkAWasW0IIK8cJgNHPn+/c8rMa2db33XfpEnRFG0m1yWjWs2L0j8kOL1FNkQw672ovIO9JG03Z0E5sMyKPreL3Gaq0cTO6F0Uov9zWkZ7Vl03j8lDIy+Kh9AHtEFv2/y2NHh4qN0FLLtY8kbVsFmvia5bcyynOKSNCcb1bXAVWQXj8AZL5gHdanJuEzHPN+f3t7lX2kSf/aXHAr/64WJSBWT6DgLvn4ww7Fx0HYyg/jtMt4air0Sy/chnXjgv7ZKo5VbfTkx1Kn3Hk5rE2dvvE+R8iQOoPZxkG4T4TAtYR1a6Uxvy7e0WGd0NI6nbUWiJySfOyB3IbEsg3w7Dz/sf5Dk7NvbxnJBjtNqCQTua2HHXM2Ymzvl0qFE7Gi+kC8TRiLXtFC7JMLs=----ATTACHMENT:----OTA4NTY5MjA3MTgwMDU0IDU1NTYxNzE4MTgwODA1MzYgNzUzNzE5MzA3MDI3NDYz