2009-12-08 47 views
1

我有一个“困境”,不知道什么是商业最佳实践。什么是验证文件名的业务最佳实践?

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

我已经看过不同的解决方案,但不能找到一个好的解决方案。

这里是我的标准:

  • 文件名必须全部使用小写
  • 文件名只能包含charaters [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
我recieving通过$ _FILES文件。这给了我下面的数据:

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

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

所以我尝试使用此代码:

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

但它只返回2号...

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

+0

'getimagesize'返回的类型可以通过'image_type_to_extension'函数转换为文件扩展名:http://us2.php.net/function.image_type_to_extension – 2009-12-08 23:51:58

+0

@Ben:请参阅我对使用getimagesize的评论。 – Steven 2009-12-09 09:51:44

回答

4

检查文件名以正则表达式。使用有关mimetype的信息。使用md5名称将文件保存在服务器上。将真实文件名存储在数据库

+0

使用md5保存文件很好。是的,我已经在DB中保存了文件名。但我是使用正则表达式的虱子。 – Steven 2009-12-08 23:16:04

+0

好的,但你想检查文件名与正则表达式? Mimetype的方式不好? – hsz 2009-12-09 00:06:43

+0

+1用'加密'文件名与md5 – TheHippo 2009-12-09 00:22:45

0

我假设您正在验证文件名以备将来用作下载文件名。

从技术角度来看,虽然保存文件名会​​很好,但从技术角度来看,您的方法听起来很合理。

如果你关心的网址是什么样子,并可能针对在未来的国际观众,一定要转换要么以变音符号的基本字符或将它们转换。德语用户(变音符号A○ÜSS)所期望的转换:

Ä = ae 
Ö = oe 
Ü = ue 

而北欧人似乎用得放心

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

等。

再就是各种重音符号的E中的...

删除那些完全导致了看起来真的 BD和乐strng在bwsr地址BR网址。

3

pathinfo()可以让你的文件名和扩展名。但是,我会警告你,不能依赖通过检查文件的文件名来测试文件的扩展名。你会想使用一个函数来实际检查文件的二进制内容。 finfo_file()可以做到这一点。噢,并且在用户提供的文件路径上使用basename()以防止路径穿越攻击,绝不会感到痛苦。

+0

如果你不知道扩展名,使用basename()会很困难。而且,你说,使用pathinfo不是最好的方法。最安全的是阅读acutal二进制文件。 – Steven 2009-12-08 23:17:49

0

这应该做你想要的一切:

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

而作为佩卡解释它,如果你想替换所有重读你可以使用下面的函数文件名:

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')); 
} 
+0

用[A-Z0-9_-]问题,是还扩展之前移除点 – Steven 2009-12-08 23:19:14

+0

@Steven(?):你至少尝试过吗?诀窍在于使用pathinfo($ filename,PATHINFO_FILENAME)和pathinfo($ filename,PATHINFO_EXTENSION),它的工作方式与您想要的一样。 – 2009-12-09 00:18:07

0

我不认为你应该“验证”文件名,如果它不是你想要的格式,你应该“修复”它。为什么拒绝一个文件只是因为有人不喜欢命名他们的文件,或者有一些不寻常的人物呢?另外,如果您使用的是图片,则可以使用getimagesize来确保其实际上是上传的图片(如果图片不是图片,则会失败)。

+0

通过验证,我的意思是检查文件名。没有文件将被拒绝,但我会删除不需要的字符。 – Steven 2009-12-09 09:43:23