/** * @param \PhpParser\Node\Expr\FuncCall $expr * @param Context $context * @return CompiledExpression */ protected function compile($expr, Context $context) { $expressionCompiler = $context->getExpressionCompiler(); $fNameExpression = $expressionCompiler->compile($expr->name); $name = $fNameExpression->getValue(); $compiler = $context->application->compiler; $exists = false; $arguments = $this->parseArgs($expr, clone $context); // is it a Closure if ($fNameExpression->isCallable() && $name instanceof ClosureDefinition) { return $name->run($this->parseArgs($expr, clone $context), $context); } // is the function name a correct string if (!$fNameExpression->isString() || !$fNameExpression->isCorrectValue()) { $context->debug('Unexpected function name type ' . $fNameExpression->getTypeName(), $expr->name); return new CompiledExpression(); } // namespace check for correct functionDefinition if ($context->scope) { $functionDefinition = $compiler->getFunctionNS($name, $context->scope->getNamespace()); } else { $functionDefinition = $compiler->getFunction($name); } // does the function exist if ($functionDefinition) { if (!$functionDefinition->isCompiled()) { $functionDefinition->compile(clone $context); } $exists = true; } else { $exists = function_exists($name); } if (!$exists) { $context->notice('language_error', sprintf('Function %s() does not exist', $expr->name->parts[0]), $expr); } else { $reflector = new Reflector(Reflector::manuallyFactory()); $functionReflection = $reflector->getFunction($name); if ($functionReflection) { $argumentsSuccessPass = $this->checkArguments($arguments, $functionReflection); // when everything is ok we run the function if ($argumentsSuccessPass && $functionReflection->isRunnable()) { array_walk($arguments, function (&$item) { /** @var CompiledExpression $item */ $item = $item->getValue(); }); return new CompiledExpression($functionReflection->getReturnType(), $functionReflection->run($arguments)); } return new CompiledExpression($functionReflection->getReturnType()); } } return new CompiledExpression(); }
/** * @return */ protected function getReflector() { if ($this->reflector) { return $this->reflector; } return $this->reflector = new Reflector(Reflector::manuallyFactory()); }
/** * @param \PhpParser\Node\Expr\FuncCall $expr * @param Context $context * @return CompiledExpression */ public function compile($expr, Context $context) { $name = $expr->name->parts[0]; $compiler = $context->application->compiler; $exists = false; $namespace = null; if ($context->scope) { $namespace = $context->scope->getNamespace(); } if ($namespace === null) { $functionDefinition = $compiler->getFunction($name); } else { $functionDefinition = $compiler->getFunctionNS($name, $namespace); } if (!$functionDefinition) { $exists = function_exists($name); } if ($functionDefinition) { if (!$functionDefinition->isCompiled()) { $functionDefinition->compile(clone $context); } $exists = true; } if (!$functionDefinition) { $reflector = new Reflector(Reflector::manuallyFactory()); $functionReflection = $reflector->getFunction($name); if ($functionReflection) { $arguments = $this->parseArgs($expr, clone $context); if ($functionReflection->isRunnable()) { array_walk($arguments, function (&$item) { /** @var CompiledExpression $item */ $item = $item->getValue(); }); return new CompiledExpression($functionReflection->getReturnType(), $functionReflection->run($arguments)); } return new CompiledExpression($functionReflection->getReturnType()); } } if (!$exists) { $context->notice('undefined-fcall', sprintf('Function %s() does not exist', $expr->name->parts[0]), $expr); } return new CompiledExpression(); }
<?php use Ovr\PHPReflection\Reflector; include_once __DIR__ . '/vendor/autoload.php'; $reflector = new Reflector(Reflector::manuallyFactory()); $reflection = $reflector->getFunction('gettype'); var_dump($reflection); var_dump($reflection->getNumberOfParameters()); var_dump($reflection->getNumberOfRequiredParameters()); var_dump($reflection->run(array(1)));
/** * @param \PhpParser\Node\Expr\FuncCall $expr * @param Context $context * @return CompiledExpression */ protected function compile($expr, Context $context) { $name = $expr->name->parts[0]; $compiler = $context->application->compiler; $exists = false; $namespace = null; if ($context->scope) { $namespace = $context->scope->getNamespace(); } if ($namespace === null) { $functionDefinition = $compiler->getFunction($name); } else { $functionDefinition = $compiler->getFunctionNS($name, $namespace); } if (!$functionDefinition) { $exists = function_exists($name); } if ($functionDefinition) { if (!$functionDefinition->isCompiled()) { $functionDefinition->compile(clone $context); } $exists = true; } if (!$functionDefinition) { $reflector = new Reflector(Reflector::manuallyFactory()); $functionReflection = $reflector->getFunction($name); if ($functionReflection) { $argumentsSuccessPass = true; $arguments = $this->parseArgs($expr, clone $context); if (count($arguments) > 0) { foreach ($arguments as $key => $argument) { $parameter = $functionReflection->getParameter($key); switch ($parameter->getType()) { case CompiledExpression::MIXED: //continue break; case CompiledExpression::INTEGER: switch ($argument->getType()) { case CompiledExpression::INTEGER: break; default: $argumentsSuccessPass = false; break; } break; case CompiledExpression::DOUBLE: switch ($argument->getType()) { case CompiledExpression::DOUBLE: break; default: $argumentsSuccessPass = false; break; } break; case CompiledExpression::NUMBER: switch ($argument->getType()) { case CompiledExpression::INTEGER: case CompiledExpression::STRING: case CompiledExpression::NUMBER: break; default: $argumentsSuccessPass = false; break; } break; case CompiledExpression::RESOURCE: switch ($argument->getType()) { case CompiledExpression::RESOURCE: break; default: $argumentsSuccessPass = false; break; } break; case CompiledExpression::ARR: switch ($argument->getType()) { case CompiledExpression::ARR: break; default: $argumentsSuccessPass = false; break; } break; case CompiledExpression::STRING: switch ($argument->getType()) { case CompiledExpression::STRING: break; default: $argumentsSuccessPass = false; break; } break; case CompiledExpression::OBJECT: switch ($argument->getType()) { case CompiledExpression::OBJECT: break; default: $argumentsSuccessPass = false; break; } break; case CompiledExpression::CALLABLE_TYPE: switch ($argument->getType()) { case CompiledExpression::CALLABLE_TYPE: break; case CompiledExpression::STRING: /** * @todo We need additional check on it */ break; /** * array($this, 'method') */ /** * array($this, 'method') */ case CompiledExpression::ARR: /** * @todo We need additional check on it */ break; default: $argumentsSuccessPass = false; break; } break; default: $argumentsSuccessPass = false; break; } } } if (count($arguments) < $functionReflection->getNumberOfRequiredParameters()) { $argumentsSuccessPass = false; } if ($argumentsSuccessPass && $functionReflection->isRunnable()) { array_walk($arguments, function (&$item) { /** @var CompiledExpression $item */ $item = $item->getValue(); }); return new CompiledExpression($functionReflection->getReturnType(), $functionReflection->run($arguments)); } return new CompiledExpression($functionReflection->getReturnType()); } } if (!$exists) { $context->notice('undefined-fcall', sprintf('Function %s() does not exist', $expr->name->parts[0]), $expr); } return new CompiledExpression(); }