我正在尝试将用户提交的文章添加到我的网站上(仅限管理员)。每篇文章都可以选择上传最多3张图片。我的数据库设置如下
文章
id
user_id
title
body
date_added
last_edited
照片
id (auto_increment)
article_id
首先我将文章保存在数据库中,然后我上传照片(暂时)然后我在数据库中创建一个新的照片记录,保存了article_id。然后我将上传的照片重命名为与照片记录的主键相同,并成为png。
$filename = $photo->id . '.png';
我认为这是防止文件形式被覆盖的好方法。这对我来说似乎有缺陷。关于如何保存我的记录和照片的任何建议?
由于
答案 0 :(得分:1)
哈希他们。
我使用PHP的MD5函数在图像上传到图库时对图像进行哈希处理。它有两个主要的好处:不同的图像不会互相覆盖,相同的图像将。这意味着每张独特的图片都有一个唯一的名称。接受上传,散列存储的数据,构建文件名(hash.extension
),检查现有文件。如果存在,请删除临时文件并仅使用现有副本。否则,重命名临时文件并保留它。您可能需要跟踪链接到每个文件的内容(以确保您不删除其他位置使用的文件),但它可以在重复项上节省大量空间,并且是获取唯一名称的简便方法。
此外,您不能只重命名文件以使用PNG扩展名,您需要将它们转换为PNG格式或保存原始扩展名。使用错误的扩展名可能会在某些地方,某些浏览器中出现问题,而且通常不正确。
答案 1 :(得分:1)
对于它的价值,这是我在上传类的文件中包含的方法,以确保我不会覆盖现有文件。我传递上传文件名($ _FILES [$ img_field] [“name”])和目录以将文件保存为参数,因此这仍然是一般方法。
private function unique_file_upload($filename, $dir) {
$filename = preg_replace("/[^.\w]/",'_',$filename);
$filename = preg_replace("/__+/",'_',$filename);
preg_match("/^(.*)\.(\w{2,4})$/",$filename,$f);
if ( file_exists( $dir . $filename ) ) {
$num = 1;
while ( file_exists( $dir . $filename ) ) {
preg_match("/^(.*)\.(\w{2,4})$/",$filename,$f);
preg_match("/(\d+)$/",$f[1],$n);
if ($n[1]) {
$x = $n[1];
$num = $n[1] + 1;
$num .= '.';
$filename = preg_replace("/$x\./",$num,$filename);
}
else {
$filename = $f[1] . $num . '.' . $f[2];
}
}
}
return $filename;
}
答案 2 :(得分:1)
使用数据库主键命名文件并没有什么问题。
我看到的唯一真正的缺点是你最终得到了相当无用的文件名。有人可能会抱怨更多描述性名称会对搜索引擎排名等有所帮助。
正如另一个答案所指出的,将文件重命名为以.png结尾不会使其成为png。如果你想真正转换图像格式,你可能想看看PHP的内置GD库(或查找ImageMagick)。
答案 3 :(得分:1)
如果图像使用自动增量主键作为名称,则绝对不可能有两个具有相同名称的图像。
散打或做任何额外的事情以确保名称的独特性是毫无价值的。更重要的是,它意味着在数据库中添加额外的图像名称字段。
图像可以被覆盖的唯一方法是重置数据库自动增量计数器,为了做到这一点,你需要删除表上的先前记录,否则计数器将被DBMS再次重新计算到最高id记录在桌子上。
换句话说,使用您的算法,您将不会有两个同名的图像。
答案 4 :(得分:0)
正确的方法是使用关联记录的主键ID存储文件。要处理“但它只是一个无用的数字”,您可以将原始文件名存储在“照片”表中。如果您允许多种图像类型,您也可以存储mime类型。
然后使用一个简单的脚本从数据库中检索文件的名称,并使用Content-disposition: attachment; filename=$filename
标头将其提供给客户端。这样,即使服务器上的文件名是(例如)“3527”,客户端也会看到“originalimagefilename.jpg”或其他任何内容的下载。