从file_get_contents()确定数据类型

时间:2011-05-24 18:40:44

标签: php types

我在PHP中编写一个命令行应用程序,它接受一个本地输入文件的路径作为参数。输入文件将包含以下内容之一:

  • JSON编码的关联数组
  • 关联数组的serialized()版本
  • serialized()关联数组
  • 的base 64编码版本
  • Base 64编码的JSON编码关联数组
  • 一个普通的旧PHP关联数组
  • 垃圾

简而言之,有一些我无法控制的不同程序将会以一种我能理解的统一方式写入此文件,一旦我实际找出格式。一旦我弄清楚如何摄取数据,我就可以运行它。

我正在考虑的是:

  • 如果文件的第一个字节是{,请尝试json_decode(),看看它是否失败。
  • 如果文件的第一个字节是<$,请尝试include(),看看它是否失败。
  • 如果文件的前三个字节匹配:[0-9],请尝试unserialize()
  • 如果不是前三个,请尝试base64_decode(),看看它是否失败。如果不:
    • 再次检查解码数据的第一个字节。
    • 如果所有这些都失败了,那就是垃圾。

对于一项非常简单的任务而言,这似乎相当昂贵。我能以更好的方式做到吗?如果是这样,怎么样?

4 个答案:

答案 0 :(得分:2)

这里没有太多优化。神奇的字节方法已经成为可行的方法。但是当然可以避免实际的反序列化功能。对每一个使用验证正则表达式是可行的(尽管meme通常比PHP实际解压嵌套数组更快)。

base64很容易探究。

可以使用正则表达式检查

jsonFastest way to check if a string is JSON in PHP?是用于在JS中保护它的RFC版本。但是编写一个完整的json (?R)匹配规则是可行的。

没有正确的解包功能,

serialize会有点困难。但是通过一些启发式方法,你可以断言它是一个序列化blob。

使用token_get_all可以更快地探测

php个数组脚本。或者,如果格式和数据足够受限,再次使用正则表达式。

这里更重要的问题是,您需要可靠性 - 还是简单性和速度?

答案 1 :(得分:1)

对于速度,您可以使用file(1)实用程序并在/usr/share/file/magic中添加“幻数”。它应该比纯PHP替代方案更快。

答案 2 :(得分:0)

您可以尝试json_decode()unserialize(),如果失败将返回NULL,然后base64_decode()再次运行。它不是很快,但是它比手工解析它们更容易出错......

答案 3 :(得分:0)

这里的问题是,如果您不知道它可能是什么,您将需要开发一种检测算法。约定应设置扩展名(检查扩展名,如果失败,告诉谁将文件放在那里放置正确的扩展名),否则你需要检查自己。大多数检测文件实际类型的算法都会使用hereustics来确定它的内容(exe,jpg等),因为它们通常会有一些标识它们的签名。因此,如果您不知道定义的内容是什么,最好寻找特定于这些内容的功能。这有时意味着读取超过几个字节。