验证文件名的业务最佳做法是什么?

时间:2009-12-08 22:45:51

标签: php preg-replace uploadify

我有一个“困境”,并想知道什么是商业最佳实践。

我正在使用Uploadify上传图片。现在我需要在保存文件之前验证文件名。

我看过不同的解决方案,但无法找到一个好的解决方案。

以下是我的标准:

  • 文件名必须全部为小写
  • 文件名只能包含字符[a-z0-9 _-]
  • 我必须能够重命名文件

如果文件名为my.file(name).jpeg,您会怎么做?

我可以在“。”上爆炸文件名。并保存扩展名,然后内爆再次获取文件名。但不确定这是否是最好的解决方案。

我有以下功能,但有点帮助:

function getExts($filename) 
{ 
    $exts = explode("[/\\.]", $filename) ; 
    $n = count($exts)-1; 
    $exts = $exts[$n]; 
    return $exts; 
}

function validFilename($filename)
{
    $filename = str_replace(" ", "_", $filename);
    $pattern = "/[^[a-z0-9_-]/";
    return preg_replace($pattern, "", strtolower($filename));
} 

更新1
我通过$ _FILES收到文件。这给了我以下数据:

  • $ _ FILES [“file”] [“name”] - 上传文件的名称
  • $ _ FILES [“file”] [“type”] - 上传文件的类型
  • $ _ FILES [“file”] [“size”] - 上传文件的大小(字节)
  • $ _ FILES [“file”] [“tmp_name”] - 存储在服务器上的文件的临时副本的名称
  • $ _ FILES [“file”] [“error”] - 文件上传产生的错误代码

更新2
我刚发现了一些东西。我可以使用getimagesize,它将返回7个元素的数组。其中一个元素[2]是IMAGETYPE_XXX。

所以我尝试使用这段代码:

function getExts2($filename)
{
    list(,,$type) = getimagesize($filename);
    return $type;
}

但它只返回数字2 ......

(我也尝试过使用exif_imagetype,但它只能得到 PHP错误:调用未定义的函数。)

5 个答案:

答案 0 :(得分:4)

使用正则表达式检查文件名。使用有关mime类型的信息。使用md5名称在服务器上保存文件。在db。上存储真实文件名。

答案 1 :(得分:3)

pathinfo()可以为您提供文件名和扩展名。但是,我会警告你,不能通过检查文件名依赖于测试文件的扩展名。您将需要使用实际检查文件的二进制内容的函数。 finfo_file()可以做到这一点。哦,在用户提供的文件路径上使用basename()来防止路径遍历攻击永远不会受到伤害。

答案 2 :(得分:0)

我假设您正在验证文件名以供以后用作下载文件名。

虽然为了用户的利益保留文件名会很棒,但从技术角度来看,你的方法听起来很合理。

如果您关心网址的外观,并且可能会在未来针对国际受众群体,请务必将Umlauts转换为其基本字符或进行转换。德国用户(UmlautsÄÖÜß)会期待转换:

Ä = ae
Ö = oe
Ü = ue

虽然斯堪的纳维亚人似乎很放心

Ä => a
Ö => o
Ø => o

等等。

然后有各种重音字符éáó...

完全放弃这些网址会导致在地址br中真正 bd和lok strng的网址。

答案 3 :(得分:0)

这应该做你想做的一切:

$filename = preg_replace('/[^[a-z0-9_-]/', '', str_replace(' ', '_', strtolower(pathinfo($filename, PATHINFO_FILENAME)))) . pathinfo($filename, PATHINFO_EXTENSION);

正如Pekka所解释的那样,如果要替换文件名中的所有重音,可以使用以下函数:

function Unaccent($string)
{
    return preg_replace('~&([a-z]{1,2})(acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i', '$1', htmlentities($string, ENT_QUOTES, 'UTF-8'));
}

答案 4 :(得分:0)

我认为你不应该“验证”文件名,如果它不是你想要的格式,你应该“修复”它。为什么拒绝一个文件只是因为有人在命名他们的文件,或者在那里有一些不寻常的字符?此外,如果您正在使用图像,则可以使用前面提到的getimagesize来确保它实际上是已上传的图像(如果图像不是图像则应该失败)。