【发布时间】:2011-06-05 12:11:23
【问题描述】:
我正在尝试使用 serialize 命令将一组 SplFileInfo 实例存储在缓存中,但该命令引发了此异常:
Exception' with message 'Serialization of 'SplFileInfo' is not allowed
为什么不允许?
谢谢!
注意:我只是好奇。问题本身可以解决。
【问题讨论】:
标签: php
我正在尝试使用 serialize 命令将一组 SplFileInfo 实例存储在缓存中,但该命令引发了此异常:
Exception' with message 'Serialization of 'SplFileInfo' is not allowed
为什么不允许?
谢谢!
注意:我只是好奇。问题本身可以解决。
【问题讨论】:
标签: php
无法序列化基于Resources 的对象。
我想我不必解释为什么(如果您需要解释,请告诉我,即使这个问题是 OT)
对于不相信 SplFileInfo 不会存储/打开新资源的@Charles,我制作了一个小测试脚本。
如果你运行这个:
new SplFileInfo('index.php');
$link=mysql_connect('localhost','root','');
echo $link;
输出为:Resource id #2
如果你运行这个:
//new SplFileInfo('index.php');
$link=mysql_connect('localhost','root','');
echo $link;
输出是:资源 id #1。
【讨论】:
SplFileInfo 不是基于资源类型(您可能会想到SplFileObject),并且未能解释为什么资源不能被序列化也无济于事。
SplFileInfo 创建了一个资源句柄。 能否请您发布一个更全面、可验证的测试用例?
Resource id #1,有时它返回Resource id #2 所以在这一点上我真的不能说splfileinfo 是否总是打开一个新的处理程序或仅在某些情况下
SplFileInfo 无法序列化,因为 PHP 团队已将其标记为不可序列化。真的,这并不奇怪:SplFileInfo 对象包含的唯一实际数据是文件名。类中的每个方法实际上都是执行相同操作的非 OO 标准函数的包装器。这些方法调用在调用时解决,而不是在创建对象时解决,因此序列化对象不会捕获文件在序列化时的状态。
如果您尝试构建一个文件列表以供以后记住,请根据文件名构建列表。
如果您尝试在特定时间构建文件及其属性的列表,请获取这些属性并存储 那些 而不是对象。
*
请记住 PHP caches the results of stat-based functions 适合您,因此没有必要添加另一个缓存层。
Here is the C file containing the underlying mechanisms for SplFileInfo and SplFileObject。 SPL 用来打开文件句柄的方法称为spl_filesystem_file_open。如果您搜索该文件,您将看到对它的四个引用。一是函数定义。一个在SplFileObject 的构造函数中。一个在 SplTempFileObject 的构造函数中。
在处理文件系统上的实体时,其中还有其他引用,称为SPL_FS_FILE 的定义。以SPL_FS_FILE 作为条件之一的switch 语句是第四个也是最后一个spl_filesystem_file_open 调用。它位于一个名为spl_filesystem_object_create_type 的函数中,该函数创建了实际 内部结构,各种基于文件系统的SPL 对象都在该结构上工作。请注意,SPL_FS_FILE 案例正上方是 SPL_FS_INFO 案例,它处理 SplFileInfo 案例,并注意该代码如何不包含打开的文件句柄。
这是SplFileInfo 不包含文件句柄资源的具体证据。
该文件还包含防止SplFileInfo 被序列化的代码,方法是将其标记为不可序列化...没有注释。该死。
在 PHP 交互式提示中进一步揭穿资源问题
[charles@duo ~/splfileinfo_test]$ touch a b c d e [charles@duo ~/splfileinfo_test]$ php -a 交互式外壳 php > $fh_a = fopen('./a', 'r'); php > 回声 $fh_a; # 应该是 1 资源 ID #2 php > # 什么。 php > $fh_b = fopen('./b', 'r'); php > 回声 $fh_b; #现在应该是……呃……3? 资源 ID #3 php > $fi_c = new SplFileInfo('./c'); php > $fh_d = fopen('./d', 'r'); php > 回声 $fh_d; # 如果 SplFileInfo 没有内部资源,则应为 4 资源 ID #4 php > 退出 [charles@duo ~/splfileinfo_test]$ php -v PHP 5.3.6 (cli) (内置: Mar 19 2011 07:44:03) 版权所有 (c) 1997-2011 PHP 集团 Zend Engine v2.3.0,版权所有 (c) 1998-2011 Zend Technologies 使用 Xdebug v2.1.0,版权所有 (c) 2002-2010,作者 Derick Rethans【讨论】:
openFile method,它返回一个SplFileObject,它将打开文件。 SplFileInfo -- 强调 Info -- 只是文件信息函数的包装,这些函数都不需要打开文件。
SplFileInfo 不包含文件句柄的具体证据更新了我的答案。
concrete evidence 也给我一些时间来研究那个.c。此外,我们比 OP 问题完全 OT