命名约定上传文件

时间:2011-05-01 20:31:20

标签: php file-upload naming-conventions

在我的网站上,我让用户上传文件。

如果文件有效并上传,则会将其移至文件夹(使用PHP)。

所有用户都上传到同一个文件夹。

我想我需要重命名上传的文件。

是否有类似默认命名约定的东西让用户上传文件名相同的文件?

5 个答案:

答案 0 :(得分:17)

没有标准惯例,但有一些最佳做法:


将文件整理到(用户和/或日期)感知文件夹

类似的东西:

/uploads/USER/ or
/uploads/[USER/]YEAR/[MONTH/[DAY/[HOUR/[MINUTE/]]]]

这将带来一些好处:


(不)重命名/清理文件名

重命名与否是您必须做出的选择,具体取决于您的网站,用户群,您想要的模糊程度,以及您的架构。您想要一个名为kate_at_the_beach.jpg1304357611.jpg的文件吗?这完全取决于你自己决定,但搜索引擎(显然)就像第一个更好。

您应该做的一件事是始终清理并规范化文件名,我个人只允许以下字符:0-9a-zA-Z_-. - 如果您选择此卫生字母表。规范化基本上意味着只需将文件名转换为小写或大写(以避免丢失文件,例如,如果您从区分大小写的文件系统切换到不区分大小写的文件系统,如Windows)。

以下是我在 phunction 中使用的一些示例代码(无耻插件,我知道:P ):

$filename = '/etc/hosts/@Álix Ãxel likes - beer?!.jpg';
$filename = Slug($filename, '_', '.'); // etc_hosts_alix_axel_likes_beer.jpg

function Slug($string, $slug = '-', $extra = null)
{
    return strtolower(trim(preg_replace('~[^0-9a-z' . preg_quote($extra, '~') . ']+~i', $slug, Unaccent($string)), $slug));
}

function Unaccent($string) // normalizes (romanization) accented chars
{
    if (strpos($string = htmlentities($string, ENT_QUOTES, 'UTF-8'), '&') !== false)
    {
        $string = html_entity_decode(preg_replace('~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|tilde|uml);~i', '$1', $string), ENT_QUOTES, 'UTF-8');
    }

    return $string;
}

处理重复的文件名

正如move_uploaded_file()上的文档条目所述:

  

如果目标文件已经存在   存在,它将被覆盖。

所以,在你调用move_uploaded_file()之前,你最好检查一下文件是否已经存在,如果确实存在,那么你应该(如果你不想丢失旧文件)重命名你的新文件,通常是追加时间/ random / unique token 文件扩展名之前,执行以下操作:

if (file_exists($output . $filename) === true)
{
    $token = '_' . time(); // see below
    $filename = substr_replace($filename, $token, strrpos($filename, '.'), 0);
}

move_uploaded_file($_FILES[$input]['tmp_name'], $output . $filename);

这将在文件扩展名之前插入$token,如上所述。至于$token值的选择,您有以下几种选择:

  • time() - 每秒确保唯一性,但是处理重复文件很糟糕
  • 随机 - 不是一个好主意,因为它不能确保唯一性并且不会处理重复
  • 唯一 - 使用文件 内容 的哈希是我最喜欢的方法,因为它保证 内容 唯一性并节省高清空间,因为您最多只能有2个相同的文件(一个带有原始文件名,另一个带有附加的散列),示例代码:

(虚拟文本,以便下一行格式化为代码。)

$token = '_' . md5_file($_FILES[$input]['tmp_name']);

希望它有所帮助! ;)

答案 1 :(得分:3)

没有这样的约定,但通常,名称是随机生成的,以使猜测不太可能。强烈建议不要使用文件名而不进行清理,至少采用白名单方法删除除白名单中的字符之外的所有字符。关键是安全性,上传是一个危险的功能,如果处理不当可能会很危险。

答案 2 :(得分:2)

自己在内部做一些约定。例如,您可以将文件作为userId_timestamp存储在文件夹中,并将原始文件名保存在某个数据库中。或者你只是将它userId_originalFilename或其他一些使其独特的组合。

答案 3 :(得分:1)

在类似的情况下,我将信息保存在一个表中(用户ID作为外键),格式化文件名前导零的自动数字ID(即000345.jpg)并将原始名称存储在表中。

答案 4 :(得分:0)

您可以使用用户名和上传日期的某种组合吗?