/** * @return self */ public static function from($from) : self { if (is_string($from) && strpos($from, '::')) { $from = new \ReflectionMethod($from); } elseif (is_array($from)) { $from = new \ReflectionMethod($from[0], $from[1]); } elseif (!$from instanceof \ReflectionFunctionAbstract) { $from = new \ReflectionFunction($from); } $method = new static(); $method->name = $from->isClosure() ? NULL : $from->getName(); foreach ($from->getParameters() as $param) { $method->parameters[$param->getName()] = Parameter::from($param); } if ($from instanceof \ReflectionMethod) { $method->static = $from->isStatic(); $method->visibility = $from->isPrivate() ? 'private' : ($from->isProtected() ? 'protected' : NULL); $method->final = $from->isFinal(); $method->abstract = $from->isAbstract() && !$from->getDeclaringClass()->isInterface(); $method->body = $from->isAbstract() ? FALSE : ''; } $method->returnReference = $from->returnsReference(); $method->variadic = PHP_VERSION_ID >= 50600 && $from->isVariadic(); $method->comment = $from->getDocComment() ? preg_replace('#^\\s*\\* ?#m', '', trim($from->getDocComment(), "/* \r\n\t")) : NULL; if (PHP_VERSION_ID >= 70000 && $from->hasReturnType()) { $returnType = $from->getReturnType(); $method->returnType = $returnType->isBuiltin() ? (string) $returnType : '\\' . $returnType; } return $method; }
public static function getRealClassName($value) { if (!is_callable($value)) { return null; } $closure = new \ReflectionFunction($value); if ($closure->hasReturnType() !== false) { $returnedType = $closure->getReturnType(); if ($returnedType->isBuiltin() === false && class_exists((string) $returnedType)) { return (string) $returnedType; } } return null; }
private function validateSignature(callable $filter = null) { $reflection = new \ReflectionFunction($filter); if ($reflection->getNumberOfParameters() !== 1) { throw new \Exception("invalid number of parameters"); } $parameter = $reflection->getParameters()[0]; $name = $parameter->getName(); if (!$parameter->hasType()) { throw new \Exception("missing required type for parameter '{$name}'"); } $type = $parameter->getType(); if ((string) $type !== "ReflectionClass") { throw new \Exception("invalid type for type for parameter '{$name}'"); } if (!$reflection->hasReturnType()) { throw new \Exception("missing required return type"); } $returnType = $reflection->getReturnType(); if ((string) $returnType !== "bool") { throw new \Exception("invalid return type"); } }
<?php function foo(int $a) : bool { } $rf = new ReflectionFunction('foo'); echo "--Parameter--\n\n"; $rp = $rf->getParameters()[0]; var_dump($rp->hasType()); $rt = $rp->getType(); var_dump($rt->isBuiltin()); var_dump($rt->__toString()); var_dump($rt->allowsNull()); echo "\n--Return--\n\n"; var_dump($rf->hasReturnType()); $rt = $rf->getReturnType(); var_dump($rt->isBuiltin()); var_dump($rt->__toString()); var_dump($rt->allowsNull()); echo "\n--Call Constructor Directly--\n\n"; // There is a public constructor; we differ with PHP 7 a bit here. In PHP 7 // you can call the public constructor from user code and then you fatal on // the first method call to the instance. In HHVM, you can call the constructor // directly, but you have to have an instance of ReflectionParameter or // ReflectionFunctionAbstract. $rt2 = new ReflectionType($rp); // this returns false since we didn't pass any info to the constructor var_dump($rt2->isBuiltin()); // This will trigger an error since it is not ReflectionParameter or // ReflectionFunctionAbstract $rt3 = new ReflectionType(new ReflectionClass('Exception'));
public function testGetReturnTypeMethod() { if (PHP_VERSION_ID < 70000) { $this->markTestSkipped('Test available only for PHP7.0 and newer'); } $fileName = stream_resolve_include_path(__DIR__ . self::STUB_FILE70); $reflectionFile = new ReflectionFile($fileName); include $fileName; foreach ($reflectionFile->getFileNamespaces() as $fileNamespace) { foreach ($fileNamespace->getFunctions() as $refFunction) { $functionName = $refFunction->getName(); $originalRefFunction = new \ReflectionFunction($functionName); $hasReturnType = $refFunction->hasReturnType(); $this->assertSame($originalRefFunction->hasReturnType(), $hasReturnType, "Presence of return type for function {$functionName} should be equal"); if ($hasReturnType) { $parsedReturnType = $refFunction->getReturnType(); $originalReturnType = $originalRefFunction->getReturnType(); $this->assertSame($originalReturnType->allowsNull(), $parsedReturnType->allowsNull()); $this->assertSame($originalReturnType->isBuiltin(), $parsedReturnType->isBuiltin()); $this->assertSame($originalReturnType->__toString(), $parsedReturnType->__toString()); } else { $this->assertSame($originalRefFunction->getReturnType(), $refFunction->getReturnType()); } } } }