PHP无原生phpinfo() JSON输出,必须用ob_start()捕获HTML后正则解析为数组再json_encode;或用php -i命令配合parse_ini_string()获取ini配置,但二者均无法覆盖全部phpinfo信息。

PHP 本身不提供原生的 phpinfo() JSON 输出模式,必须自行捕获并解析其 HTML 输出,再结构化为 JSON —— 这是唯一可行路径,不存在“开启某个参数就自动输出 JSON”的捷径。
为什么不能直接调用 phpinfo() 并期望得到 JSON
phpinfo() 是纯 HTML 渲染函数,内部硬编码输出表格和段落,不返回字符串、不接受格式参数、无法拦截输出流以外的方式获取内容。试图用 json_encode(phpinfo()) 会先输出 HTML 到浏览器,再返回 null,最终 JSON 里只有 null。
- 它没有返回值(返回
bool(true),但无实际数据) - 它不支持
INFO_JSON或类似常量(该常量根本不存在) - 启用
output_buffering是必要前提,否则ob_get_contents()拿不到任何东西
用 ob_start() + 正则提取关键区块转数组
最轻量、兼容性最好的方式:开启输出缓冲 → 调用 phpinfo() → 获取 HTML → 用正则匹配「模块名」「指令名」「本地值」「主值」四列结构,构建嵌套数组。适用于 PHP 5.6–8.3,无需额外扩展。
- 关键正则:
/
/s* ]*>([^/s* ]*>([^/s* ]*>([^/s* ]*>([^/s*/i - 需跳过头部大标题行(如
PHP Version所在的)和空行
- 对
Loaded Modules、Environment等非表格区块,需单独用preg_match_all('/
(.*?).*?
(.*?)/is', $html, $matches) 提取
- 字段值中的
、需用strip_tags()和html_entity_decode()清洗ob_start(); phpinfo(INFO_GENERAL | INFO_CONFIGURATION | INFO_MODULES); $html = ob_get_clean(); // 简单示例:只提取核心配置项(非完整实现) $pattern = '/
/s* ]*>([^<]+)/td>/s* ]*>([^<]+)/td>/s* ]*>([^<]+)/td>/s* ]*>([^<]+)/td>/s*/tr>/i'; preg_match_all($pattern, $html, $matches, PREG_SET_ORDER); $config = []; foreach ($matches as $m) { $key = trim($m[1]); $local = trim(html_entity_decode(strip_tags($m[3]))); $master = trim(html_entity_decode(strip_tags($m[4]))); if ($key && ($local !== '' || $master !== '')) { $config[$key] = ['local' => $local ?: null, 'master' => $master ?: null]; } } echo json_encode(['config' => $config], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); 用
php -i命令行 +json_encode(parse_ini_string())替代方案如果目标是获取
php.ini配置项(而非全部phpinfo()内容),命令行方式更干净:它输出纯文本键值对,可直接用parse_ini_string()解析。立即学习“PHP免费学习笔记(深入)”;
- 执行
php -i | grep -E '^(memory_limit|upload_max_filesize|date/.timezone)'可筛选特定项 - 完整输出:
$text = shell_exec('php -i 2>/dev/null');,但注意:某些 ini 值含冒号或括号(如extension=redis.so),parse_ini_string()默认不支持,需手动预处理换行和等号对齐 - 不包含运行时模块信息(如
gd是否启用)、环境变量、HTTP 头等 Web 上下文数据 - 在禁用
shell_exec的共享主机上不可用
容易被忽略的坑:模块差异与字符编码
phpinfo()HTML 输出默认用 ISO-8859-1 编码(尤其旧版本),而json_encode()要求 UTF-8。若页面含中文模块名(如某些自定义扩展),未转码会导致json_encode()返回false。- 务必在
ob_start()前加header('Content-Type: text/html; charset=utf-8');并确保mb_internal_encoding('UTF-8') -
gd、imagick等图像扩展的版本信息可能含 Unicode 版权符号(©),需mb_convert_encoding($html, 'UTF-8', 'auto') -
INFO_VARIABLES区块里$_SERVER输出的是当前 CGI 环境变量,不是 Web Server 的真实值(如 Apache 的mod_rewrite状态不会体现) - 某些 SAPI(如 PHP-FPM)下,
phpinfo(INFO_MODULES)可能漏掉动态加载的 .so 文件,需结合get_loaded_extensions()补全
- 需跳过头部大标题行(如
