有没有一种方法可以只使用数据来了解文件类型


Is there a way to know the file type with only the data

由于一些技术问题,我无法以传统方式将文件从输入发送到后端。我必须从文件中读取数据,将其绑定到模型,并将数据(作为一个巨大的字符串)发送到服务器。假设我的用户上传了一个.jpg,我的代码看起来像这样:

// This return the data in the form of a simple string.
$data = $this->getRequest()->request->get('document[document_file]', null, true);
// Let's assume that I know what type of file my user send me
$data = explode("data:image/jpeg;base64,", $file);
$data = base64_decode($data[1]);
$image = imagecreatefromstring($data);
imagejpeg($image, "test.jpg");

我的问题是,我不知道我的用户将上传什么类型的文件。有没有一种方法可以找出它是什么类型的文件,并以更有效的方式保存它。处理这样一个问题的更有效的方法是什么?

编辑:需要注意的一点是,它并不总是一个图像。它可以是.pdf、.doc、.txt!

由于图像的内容在字符串中,因此可以使用包含mime字段的getimagesizefromstring(),该字段将告诉您图像的类型。

$data = base64_decode($data[1]);
$info = getimagesizefromstring($data);
$mime = $info['mime'];

如果您需要支持任何文件,而不仅仅是图像,则需要编写自定义文件解析器,或者,如果您有FileInfo PECL扩展名,则可以使用finfo_file():

$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, '/path/to/your/file.jpg');
finfo_close($finfo);

需要注意的是,您需要一个实际的文件,而不是字符串(但您可以始终将字符串写入临时文件)。

编辑:以下是在不需要创建文件的情况下解决问题的答案。让我们从图像中获取以下数据:

data:image/jpeg;base64/9j/4AAQSkZJRgA [...] xD5epeRHJ4glkjk/sb7R5lrFJ5fmfu/wDv5W1TEV/5wp+58

你需要首先解析它首先

$data = explode(",", $data);

然后将字符串插入缓冲区

$finfo->buffer(base64_decode($data[1]))

最后,使用@JohnErck的答案来求解扩展类型。

file_put_contents($path . $filename . AppUtil::FileExt($data[1]), $data[1]);

Unix工具"file"会告诉你什么是基于开头的"幻数"的文件——也许你可以fork/shell/调用它?

示例:

file sem.pl sean.zip Windows.pdf
sem.pl:   a /usr/bin/perl script text executable
sean.zip: Zip archive data, at least v1.0 to extract
Windows.pdf: PDF document, version 1.5