Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP生成的JSON文件具有application/octet流mime类型_Php_Json_Mime Types - Fatal编程技术网

PHP生成的JSON文件具有application/octet流mime类型

PHP生成的JSON文件具有application/octet流mime类型,php,json,mime-types,Php,Json,Mime Types,我有一个从数据生成JSON文件的脚本。 我还有第二个脚本,它从目录中读取文件,只获取JSON文件并将它们插入数据库 问题是第二个脚本从我生成的文件中检测到“application/octet stream”MIME类型,而不是application/json 我不想允许application/octet-streamMIME类型,因为它可以是任何类型(出于安全原因:第二个脚本加载目录中的所有json文件(不仅仅是生成的文件)) 那么,是否仍然可以“设置”文件的MIME类型 生成文件的代码: if

我有一个从数据生成JSON文件的脚本。 我还有第二个脚本,它从目录中读取文件,只获取JSON文件并将它们插入数据库

问题是第二个脚本从我生成的文件中检测到“application/octet stream”MIME类型,而不是
application/json

我不想允许
application/octet-stream
MIME类型,因为它可以是任何类型(出于安全原因:第二个脚本加载目录中的所有
json
文件(不仅仅是生成的文件))

那么,是否仍然可以“设置”文件的MIME类型

生成文件的代码:

if($r_handle = fopen($s_file_name, 'w+')){
    fwrite($r_handle, json_encode($o_datas, JSON_HEX_QUOT | JSON_HEX_TAG));
    fclose($r_handle);
    return;
}
读取JSON文件的代码:

$o_finfo = finfo_open(FILEINFO_MIME_TYPE);
$a_mimes =& get_mimes();
if(is_dir($s_dir) && $r_handle = opendir($s_dir)){
    while($s_file = readdir($r_handle)){
        $s_file_path = $s_dir.$s_file;
        $s_mime      = finfo_file($o_finfo, $s_file_path);
        if(!in_array($s_file, array('.', '..')) && in_array($s_mime, $a_mimes['json'])){
            // Some code
        }
    }
}
扩展(与Unix命令类似的工具)基本上搜索数据库中定义的签名(称为“magic”)。如果我没记错的话,PHP的magic数据库目前被编译成扩展名二进制文件,因此您无法查看它,但您的系统中可能会有一个类似的数据库。我的Apache地址是
C:\Apache24\conf.magic
,这是JPEG的条目:

# JPEG images
0   beshort     0xffd8      image/jpeg
任何以
0xffd8
开头的内容都是图片。完成了

我对这种格式不是特别熟悉,但它似乎甚至不寻找JSON。而且,正如您可能已经猜到的,整个实用程序决不是一个安全特性。它只是一个帮助工具,用于确定文件可能包含的内容。如果您从损坏的磁盘上恢复了没有扩展名的文件,这将非常方便


MIME类型很酷。您设置了
application/json
,每个人都知道它是json。简单明了,不是吗。只有两个警告:

  • 文件系统(其中许多实际上是在MIME类型之前发明的)存储许多文件属性(名称、上次修改日期、权限,有时甚至图标…),但不存储MIME类型。(当然,可能有一些学术文件系统可以做到这一点,但FAT32、NTFS和ext4的情况并非如此……)。它通常不会添加有价值的信息,它是保持更新的另一个标志,而且它特别不可移植(将文件复制到thumb驱动器,它们就消失了)

  • 它仍然不是一个安全功能。如果我可以伪造文件内容,是什么阻止我伪造MIME类型


那么,你能做什么?最好的选择是:什么都不做

只需将文件解析为JSON并检测它是否失败。不管怎样,你都需要这样做,它告诉你你需要做的一切。JSON只是纯文本数据。也许可以添加一些检查以防止非常大的文件(同样,您应该在文件上载中执行此操作),并添加
$depth
检查,但仅此而已

if (json_decode($s_file_path, true, 32)!==null || json_last_error()!==JSON_ERROR_NONE) {
    // Valid JSON
}

不,您不能“设置”MIME类型。Finfo只是尽可能地猜测。“应用程序/八位字节流”几乎是指“不知道,我想这是一个文件”。这在技术上是一个正确的答案……如果我理解了这个问题,你可以在PHP中的文件中设置
header()
fopen()
的内容类型,对吗?@SteveKnau:我能做
header()
然后
fopen()
然后
fwrite()
吗?那没什么用处,不是。特别是对于JSON和具有不同文件扩展名的类似数据格式:尝试将其解析为JSON。如果失败,则可能是文件扩展名错误或文件已损坏。当然,在这个过程中不要让您的服务器被利用,例如,尝试将2GB JSON文件解析到内存中…