From 5c86bf39f1ae3f35d08dea6b8184deaa7981fad6 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Mon, 25 May 2026 22:34:07 +0800 Subject: [PATCH] =?UTF-8?q?feat(examples):=20=E6=B7=BB=E5=8A=A0=20PHP=20?= =?UTF-8?q?=E5=8F=8D=E5=B0=84=20API=20=E7=A4=BA=E4=BE=8B=E7=A8=8B=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现了打印内置函数参数和返回值类型信息的功能 - 添加了打印用户自定义函数信息的支持 - 实现了打印类方法参数和返回值类型信息的功能 - 添加了打印闭包(Closure)信息的支持 - 提供了完整的反射细节打印功能 - 支持联合类型、交集类型等复杂类型格式化 - 包含了 tentative return type 的 --- examples/ref/reflection_demo.php | 296 +++++++++++++++++++++++++++++++ 1 file changed, 296 insertions(+) create mode 100644 examples/ref/reflection_demo.php diff --git a/examples/ref/reflection_demo.php b/examples/ref/reflection_demo.php new file mode 100644 index 00000000..905e9a05 --- /dev/null +++ b/examples/ref/reflection_demo.php @@ -0,0 +1,296 @@ +getMessage() . PHP_EOL; + } +} + +/** + * 打印类方法的参数和返回值类型信息 + * + * @param string $className 类名 + * @param string $methodName 方法名 + */ +function printMethodReflection(string $className, string $methodName): void +{ + try { + $ref = new ReflectionMethod($className, $methodName); + printReflectionDetails($ref); + } catch (ReflectionException $e) { + echo " [错误] " . $e->getMessage() . PHP_EOL; + } +} + +/** + * 打印反射细节(通用,适用于 ReflectionFunction / ReflectionMethod) + */ +function printReflectionDetails(ReflectionFunctionAbstract $ref): void +{ + // 名称 + $name = $ref instanceof ReflectionMethod + ? $ref->getDeclaringClass()->getName() . '::' . $ref->getName() + : $ref->getName(); + echo " 名称: {$name}" . PHP_EOL; + + // 是否内置 + echo " 类型: " . ($ref->isInternal() ? '内置函数' : '用户自定义') . PHP_EOL; + + // 是否为静态方法 + if ($ref instanceof ReflectionMethod) { + echo " 静态: " . ($ref->isStatic() ? '是' : '否') . PHP_EOL; + } + + // 是否为可变参数 + echo " 可变参数: " . ($ref->isVariadic() ? '是' : '否') . PHP_EOL; + + // 参数信息 + $params = $ref->getParameters(); + echo " 参数个数: " . count($params) . PHP_EOL; + + foreach ($params as $i => $param) { + echo " 参数 #{$i}: \${$param->getName()}" . PHP_EOL; + + // 类型 + $type = $param->getType(); + if ($type) { + echo " 类型: " . formatType($type) . PHP_EOL; + } else { + echo " 类型: (未声明)" . PHP_EOL; + } + + // 默认值 + if ($param->isDefaultValueAvailable()) { + $defaultValue = $param->getDefaultValue(); + echo " 默认值: " . formatDefaultValue($defaultValue) . PHP_EOL; + } + + // 是否为可变参数 + if ($param->isVariadic()) { + echo " (可变参数)" . PHP_EOL; + } + + // 是否可为 null + if ($type && $type->allowsNull()) { + echo " 允许 null: 是" . PHP_EOL; + } + + // 是否为引用传递 + if ($param->isPassedByReference()) { + echo " 引用传递: 是" . PHP_EOL; + } + } + + // 返回值类型 + $returnType = $ref->getReturnType(); + if ($returnType) { + echo " 返回值类型: " . formatType($returnType) . PHP_EOL; + } else { + echo " 返回值类型: (未声明)" . PHP_EOL; + } + + // Tentative Return Type (PHP 8.0+,主要用于内置函数/方法) + $tentativeReturnType = $ref->getTentativeReturnType(); + if ($tentativeReturnType) { + echo " Tentative 返回值类型: " . formatType($tentativeReturnType) . PHP_EOL; + echo ' 说明: 这是 PHP 8.0+ 为旧版内置函数/方法添加的【暂定返回值类型】,不强制要求继承类或用户代码实现' . PHP_EOL; + } else { + echo " Tentative 返回值类型: (未声明)" . PHP_EOL; + } +} + +/** + * 格式化类型信息(支持联合类型、交集类型等) + */ +function formatType(ReflectionType $type): string +{ + if ($type instanceof ReflectionUnionType) { + $types = []; + foreach ($type->getTypes() as $t) { + $types[] = formatNamedType($t); + } + return implode(' | ', $types); + } + + if ($type instanceof ReflectionIntersectionType) { + $types = []; + foreach ($type->getTypes() as $t) { + $types[] = formatNamedType($t); + } + return implode(' & ', $types); + } + + if ($type instanceof ReflectionNamedType) { + return formatNamedType($type); + } + + return (string)$type; +} + +/** + * 格式化命名类型 + */ +function formatNamedType(ReflectionNamedType $type): string +{ + $prefix = $type->allowsNull() && $type->getName() !== 'mixed' ? '?' : ''; + return $prefix . $type->getName(); +} + +/** + * 格式化默认值显示 + */ +function formatDefaultValue(mixed $value): string +{ + if ($value === null) { + return 'null'; + } + if (is_bool($value)) { + return $value ? 'true' : 'false'; + } + if (is_string($value)) { + return "'{$value}'"; + } + if (is_array($value)) { + return '[]'; + } + if (is_float($value)) { + return var_export($value, true); + } + return (string)$value; +}