在多字节字符串(Multibyte String)处理时,PHP 的 mbstring 扩展扮演了极其重要的角色。其中 mb_get_info() 是一个常用的函数,用来查看当前 mbstring 的配置信息,比如当前编码、检测顺序等等。
随着 PHP 从 7.x 时代过渡到 8.x,mb_get_info() 也发生了一些微妙但重要的变化。本文将详细介绍这些变化,以及它们可能带来的兼容性问题。
在 PHP 7.x 中,mb_get_info() 有两种调用方式:
无参数调用:返回所有的 mbstring 配置信息,结果是一个关联数组。
带参数调用:可以传递一个字符串参数,比如 'internal_encoding',返回对应的配置信息。
示例代码:
<?php
// 获取全部 mbstring 配置信息
$info = mb_get_info();
print_r($info);
// 获取特定的配置信息
$internalEncoding = mb_get_info('internal_encoding');
echo "Internal Encoding: " . $internalEncoding;
?>
这些信息可以帮助开发者了解当前环境的字符集设定,尤其是在处理国际化应用时非常重要。
进入 PHP 8.x 之后,mb_get_info() 进行了以下调整:
部分配置信息字段被废弃。
比如,以前的一些过时字段(如 http_input, http_output)在 PHP 8 中已经彻底移除,因为 mbstring 不再处理 HTTP 输入输出了。这些内容现在统一交由 PHP 流和输入过滤器处理。
返回的字段数量减少。
如果你的代码依赖了某些已经废弃的键名,比如 http_output,在 PHP 8 中使用 mb_get_info() 将不会再返回它们。
类型声明加强。
在 PHP 8 中,mb_get_info() 的返回值类型更加严格,不会像以前那样松散返回 false 或其他奇怪的结果。
错误处理方式改变。
如果传递了无效的参数,以前可能悄无声息地返回 false,现在在 PHP 8 中可能会抛出 TypeError 或 ValueError。
PHP 8.x 示例代码:
<?php
// 获取全部 mbstring 配置信息
$info = mb_get_info();
foreach ($info as $key => $value) {
echo "{$key} : {$value}\n";
}
// 获取 internal_encoding 信息
try {
$encoding = mb_get_info('internal_encoding');
echo "Internal Encoding: " . $encoding;
} catch (ValueError $e) {
echo "Caught error: " . $e->getMessage();
}
?>
如果你打算将代码从 PHP 7.x 升级到 PHP 8.x,使用 mb_get_info() 需要注意以下兼容性问题:
如果代码中有像这样直接访问被废弃字段的逻辑:
<?php
$httpOutput = mb_get_info()['http_output'];
?>
那么在 PHP 8 中将直接报错,提示未定义的数组键。
解决方法:必须改写,避免依赖这些已经消失的键名。
<?php
$info = mb_get_info();
if (isset($info['http_output'])) {
$httpOutput = $info['http_output'];
} else {
$httpOutput = 'default'; // 或者给出合理的默认值
}
?>
如果代码中随意传递参数到 mb_get_info(),在 PHP 7 中可能只是返回 false,但在 PHP 8 中会直接抛异常。例如:
<?php
// PHP 7.x 可能返回 false
var_dump(mb_get_info('non_existing_field'));
// PHP 8.x 会抛出 ValueError
?>
建议:加上异常捕获逻辑,提升代码健壮性。
为了确保一套代码能同时运行在 PHP 7 和 PHP 8,可以参考如下写法:
<?php
function safe_mb_get_info(string $option = null) {
try {
if ($option !== null) {
return mb_get_info($option);
}
return mb_get_info();
} catch (Throwable $e) {
// 记录日志,或者返回默认值
error_log("mb_get_info error: " . $e->getMessage());
return null;
}
}
// 使用
$encoding = safe_mb_get_info('internal_encoding');
echo $encoding ?? 'utf-8';
?>
如果需要了解更多关于 mbstring 和 mb_get_info() 的官方信息,可以访问 https://gitbox.net/php/manual/en/function.mb-get-info.php。
建议在升级项目之前,使用工具如 PHPStan 或 Psalm 做一次代码静态分析,及时发现潜在的 API 兼容性问题。
总体来看,mb_get_info() 在 PHP 8.x 中变得更干净、严格、现代化,但也带来了兼容性挑战。升级项目时,特别是涉及多语言、字符编码敏感的系统,必须仔细检查并适配这些变化,避免上线后出现奇怪的字符处理问题。
谨记:编码处理的问题,往往是最容易被忽略、但影响最大的。