PHP:序列化数组保存在(人类)不可读的 UTF-16LE 编码 .txt 文件中——错误或预期行为?
PHP: Serialized array is saved in (by humans) unreadable UTF-16LE encoded .txt file -- bug or intended behaviour?
我正在 PHP 自学面向对象编程网站(使用 XAMPP 版本 7.3.14 Windows),最近我学习了如何保存包含对象的序列化数组( file_put_contents('path/filename.txt', serialize($array));
)。我已经用普通数组做了这个。为了练习一下,我写了一个小网站,有一个添加新记录的表单模板和一个在屏幕上打印出带有个别记录链接的列表的显示模板,我遇到了以下现象:
在对象的 class 定义中(实例化为一维数值数组的元素)我正在使用所有属性初始化为 protected
并获取并设置它们的值getter 和 setter 方法在 class 定义之外的实际程序代码中。当我向数组添加一条新记录(此时仍从 PHP 代码中读取)并第一次保存数组时,生成的 .txt 文件以 UTF-8 编码,序列化字符串显示"normal" 拉丁字母语法如:
a:4:{i:0;O:8:"stdClass":6:{s:13:" * property_1"; s:7:"value_1"; ...
然而,在我修改了程序代码,使数据现在从 .txt 文件 (unserialize(file_get_contents('path/filename.txt', $array));
) 中读取并再次保存后,生成的文件编码为 UTF- 16LE 并且包含中文字符,所以它对我来说是不可读的!尽管如此,PHP 解释器显然仍然可以读取该文件。进一步测试表明,这种行为似乎与属性的保护状态有关。将属性的初始化模式更改为 public
后,会读取 UTF-16LE 编码文件,但再次保存时会变回 "normal" UTF-8 编码文件。
最后我的问题是:这是已知行为还是我的 PHP 解释器的错误?当我在网上搜索时,我没有找到任何符合我观察的东西。
PHP 序列化不是人类可读的格式。您还可以在手册中看到:
Note that this is a binary string which may include null bytes
https://www.php.net/manual/en/function.serialize.php
私有和受保护的属性带来空字节。例如
class A{
private $b='0';
}
echo bin2hex(serialize(new A())), PHP_EOL;
echo serialize(new A());
输出
4f3a313a2241223a313a7b733a343a2200410062223b733a313a2230223b7d
O : 1 : " A " : 1 : { s : 4 : " A b " ; s : 1 : " 0 " ; }
^ ^
| | null bytes
^
| class name for private or * for protected
空字节字符串不可打印,因此,您的文本编辑器"decided"需要其他编码。
我正在 PHP 自学面向对象编程网站(使用 XAMPP 版本 7.3.14 Windows),最近我学习了如何保存包含对象的序列化数组( file_put_contents('path/filename.txt', serialize($array));
)。我已经用普通数组做了这个。为了练习一下,我写了一个小网站,有一个添加新记录的表单模板和一个在屏幕上打印出带有个别记录链接的列表的显示模板,我遇到了以下现象:
在对象的 class 定义中(实例化为一维数值数组的元素)我正在使用所有属性初始化为 protected
并获取并设置它们的值getter 和 setter 方法在 class 定义之外的实际程序代码中。当我向数组添加一条新记录(此时仍从 PHP 代码中读取)并第一次保存数组时,生成的 .txt 文件以 UTF-8 编码,序列化字符串显示"normal" 拉丁字母语法如:
a:4:{i:0;O:8:"stdClass":6:{s:13:" * property_1"; s:7:"value_1"; ...
然而,在我修改了程序代码,使数据现在从 .txt 文件 (unserialize(file_get_contents('path/filename.txt', $array));
) 中读取并再次保存后,生成的文件编码为 UTF- 16LE 并且包含中文字符,所以它对我来说是不可读的!尽管如此,PHP 解释器显然仍然可以读取该文件。进一步测试表明,这种行为似乎与属性的保护状态有关。将属性的初始化模式更改为 public
后,会读取 UTF-16LE 编码文件,但再次保存时会变回 "normal" UTF-8 编码文件。
最后我的问题是:这是已知行为还是我的 PHP 解释器的错误?当我在网上搜索时,我没有找到任何符合我观察的东西。
PHP 序列化不是人类可读的格式。您还可以在手册中看到:
Note that this is a binary string which may include null bytes
https://www.php.net/manual/en/function.serialize.php
私有和受保护的属性带来空字节。例如
class A{
private $b='0';
}
echo bin2hex(serialize(new A())), PHP_EOL;
echo serialize(new A());
输出
4f3a313a2241223a313a7b733a343a2200410062223b733a313a2230223b7d
O : 1 : " A " : 1 : { s : 4 : " A b " ; s : 1 : " 0 " ; }
^ ^
| | null bytes
^
| class name for private or * for protected
空字节字符串不可打印,因此,您的文本编辑器"decided"需要其他编码。