命名约定上传文件

Pee*_*Haa 6 php file-upload naming-conventions

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

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

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

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

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

Ali*_*xel 17

没有标准的约定,但有一些最佳实践:


将文件组织到(用户和/或日期)感知文件夹中

就像是:

/uploads/USER/ or
/uploads/[USER/]YEAR/[MONTH/[DAY/[HOUR/[MINUTE/]]]]
Run Code Online (Sandbox Code Playgroud)

这将有一些好处:


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

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

有一件事你应该做的是始终消毒和规范的文件名,我个人只允许下列字符:0-9,a-z,A-Z,_,-,.-如果你选择了这个卫生字母.规范化基本上意味着只需将文件名转换为小写或大写(以避免丢失文件,例如,如果您从区分大小写的文件系统切换到不区分大小写的文件系统,如Windows).

这是我在功能中使用的一些示例代码(无耻插件,我知道: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;
}
Run Code Online (Sandbox Code Playgroud)

处理重复的文件名

作为move_uploaded_file()状态的文档条目:

如果目标文件已存在,则将覆盖该文件.

所以,在你打电话给move_uploaded_file()你之前,检查文件是否已经存在,如果确实存在,那么你应该(如果你不想丢失旧文件)重命名你的新文件,通常在文件附加一个时间/随机/唯一标记做扩展,做这样的事情:

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);
Run Code Online (Sandbox Code Playgroud)

这将具有插入$token文件扩展名之前的效果,如上所述.至于$token价值的选择,你有几个选择:

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

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

$token = '_' . md5_file($_FILES[$input]['tmp_name']);
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你!;)