检查上传的文件是不是为 csv 格式
Posted
技术标签:
【中文标题】检查上传的文件是不是为 csv 格式【英文标题】:Check file uploaded is in csv format检查上传的文件是否为 csv 格式 【发布时间】:2011-10-03 00:26:38 【问题描述】:我正在用 php 上传一个文件,如果它是一个 csv 文件,我只想上传它。我相信我的语法适合内容类型。当它是 csv 文件时,它总是转到 else 语句。我在这里做错了什么?
if (($_FILES["file"]["type"] == "text/csv"))
else
如果我更改内容类型,它适用于该格式,但不适用于 csv。
【问题讨论】:
$_FILES["file"]["type"] 永远不应依赖于文件类型验证。此外,似乎没有真正的方法来验证文件是否实际上是 csv 文件。 os-code-web.blogspot.com/2011/04/… 我总是验证传入文件的内容,而不是依赖于 MIME 类型。 只有受信任的用户才会使用这个网站,所以我现在不需要内容验证。我只是想确保他们不会错误地上传其他文件。当需要时,我将分支并进行内容验证。 【参考方案1】:mime 类型可能不是text/csv
某些系统可以以不同的方式读取/保存它们。 (例如,有时 IE 将 .csv 文件作为application/vnd.ms-excel
发送)所以最好的办法是构建一个允许值的数组并对其进行测试,然后找到所有可能的值进行测试。
$mimes = array('application/vnd.ms-excel','text/plain','text/csv','text/tsv');
if(in_array($_FILES['file']['type'],$mimes))
// do something
else
die("Sorry, mime type not allowed");
如果您希望进一步检查 mime 是否以 text/plain 形式返回,您可以运行 preg_match
以确保其中有足够的逗号作为 csv。
【讨论】:
我必须将“application/octet-stream”添加到数组中以验证我的 csv 文件(从 GMail 联系人中导出) 您应该经常检查内容,当文件实际上是 csv 但具有一些奇怪的 mime 类型(如 application/x-msdownload)时,此方法很容易失败。 CSV 可以是 application/x-msdownload,但 XLS 也可以,所以这很糟糕。 看看这个帖子***.com/questions/2450345/how-to-validate-csv-file -1。这段代码是错误的。这取决于用户的浏览器认为以 .csv 结尾的文件名的正确 MIME 类型。此外,如果用户将 .jpeg 重命名为以 .csv 结尾,此代码仍将允许它有效。为了根据提问者的评论进行快速的完整性检查(即用户没有意外选择错误的文件),检查文件扩展名要简单得多。要查看 CSV 文件是否对您的应用程序有效,请尝试按照应用程序的规则处理 CSV 文件;如果失败,则无效。 如果您将txt
文件重命名为csv
然后上传文件,此代码将不起作用【参考方案2】:
CSV 文件有很多可能的 MIME 类型,具体取决于用户的操作系统和浏览器版本。
这是我目前验证 CSV 文件的 MIME 类型的方式:
$csv_mimetypes = array(
'text/csv',
'text/plain',
'application/csv',
'text/comma-separated-values',
'application/excel',
'application/vnd.ms-excel',
'application/vnd.msexcel',
'text/anytext',
'application/octet-stream',
'application/txt',
);
if (in_array($_FILES['upload']['type'], $csv_mimetypes))
// possible CSV file
// could also check for file content at this point
【讨论】:
text/plain
也允许上传 .txt 文件
-1。这段代码是错误的。这取决于用户的浏览器认为以 .csv 结尾的文件名的正确 MIME 类型。此外,如果用户将 .jpeg 重命名为以 .csv 结尾,此代码仍将允许它有效。要查看 CSV 文件是否对您的应用程序有效,请尝试按照应用程序的规则处理 CSV 文件;如果失败,则无效。
旧线程,但想从 OpenOffice 添加一个电子表格 mime。 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'【参考方案3】:
你不能总是依赖 MIME 类型..
根据:http://filext.com/file-extension/CSV
text/comma-separated-values, text/csv, application/csv, application/excel, application/vnd.ms-excel, application/vnd.msexcel, text/anytext
CSV 有多种 MIME 类型。
您可能最好检查扩展程序,同样不是很可靠,但对于您的应用程序,它可能没问题。
$info = pathinfo($_FILES['uploadedfile']['name']);
if($info['extension'] == 'csv')
// Good to go
代码未经测试。
【讨论】:
我认为您会检查$_FILES['uploadedfile']['name']
与 tmp_name
,因为 tmp_name 是服务器上的临时文件名。至少在我的情况下,tmp_name 不包括原始文件扩展名。
$extension = pathinfo($_FILES['csvFileRep']['name'], \PATHINFO_EXTENSION);【参考方案4】:
由于您担心用户错误地上传其他文件,我建议您在<input>
标签中使用accept=".csv"
。当用户上传文件时,它只会在浏览器中显示 csv 文件。如果您找到了更好的解决方案,请告诉我,因为我也在尝试在相同的条件下做同样的事情 - '受信任的用户,但试图避免错误'
【讨论】:
嗯..这确实有助于让用户选择正确的文件类型,但对确保文件是有效的 csv 文件没有任何作用。 至少对于扩展检查来说绝对完美 7 年后,这仅在文件上传窗口(win 10)上预先选择了 csv 选项,用户可以选择 *All Files (.) 选项并仍然上传任何其他类型。所以最好不要在野外使用。【参考方案5】:所以我今天遇到了这个。
试图通过查看$_FILES['upload_file']['type']
来验证上传的 CSV 文件的 MIME 类型,但对于使用各种浏览器的某些用户(并且所述用户之间不一定使用相同的浏览器;例如,它在 FF 中对我来说很好,但在另一个用户它在 FF 上不起作用)$_FILES['upload_file']['type']
以“application/vnd.ms-excel”的形式出现,而不是预期的“text/csv”或“text/plain”。
所以我求助于使用(恕我直言)更可靠的 finfo_* 函数,如下所示:
$acceptable_mime_types = array('text/plain', 'text/csv', 'text/comma-separated-values');
if (!empty($_FILES) && array_key_exists('upload_file', $_FILES) && $_FILES['upload_file']['error'] == UPLOAD_ERR_OK)
$tmpf = $_FILES['upload_file']['tmp_name'];
// Make sure $tmpf is kosher, then:
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime_type = finfo_file($finfo, $tmpf);
if (!in_array($mime_type, $acceptable_mime_types))
// Unacceptable mime type.
【讨论】:
【参考方案6】:Mime 类型选项不是验证 CSV 文件的最佳选项。我使用了这段代码,这在所有浏览器中都运行良好
$type = explode(".",$_FILES['file']['name']);
if(strtolower(end($type)) == 'csv')
else
【讨论】:
这只会检查用户的文件是否以.csv
结尾,而不是文件是否是有效的CSV【参考方案7】:
简单地使用“接受”和“需要” 并避免如此多的典型和不需要的编码。
【讨论】:
您的服务器端逻辑如何检查用户输入?或者你根本不做后端验证?以上是关于检查上传的文件是不是为 csv 格式的主要内容,如果未能解决你的问题,请参考以下文章
需要保存为CSV格式上传身份号,从Excel复制文本过去,CSV里后几位都是000,怎么办?必须要保存为CSV上传