多人多页面多图片上传问题??

现在要上传产品图片,但不是一个人上传。而是2、3十个人同时上传,每个人打开2-3个上传产品的页面,然后基本上同时上传。

因为上传图片需要一定的时间,假设每张图片5M大小,单次个人单页面上传50张图片。由于肯定需要一段时间的,假设用户A打开一个页面,上传50张,图片在慢慢上传;用户A肯定不会闲着,由打开一个上传产品的页面,再次上传50张图片;同理用户B也是如此,用户C也是如此.....,图片上传需要一段时间,可能在10分钟内或1-2分钟内同时有多个用户单浏览器开了多个页面(甚至多浏览器多页面)进行上传。

这个时候后台需要对已上传的图片做重命名处理,以确保那么多图片不会重名。

如果采取 用户id + 时间戳(秒级的) 的形式不行。因为他只能具体到秒。而一秒钟内上传上传完成并进行重命名的图片太多了,不行。

我目前想到的时根据 用户id + 时间戳(微妙级的) + 针对当前页面生成的唯一id 来进行重命名,降低图片重名的概率。

有没有完美的办法解决上传图片重名的问题??

跪求大神了!!

阅读 4.2k
4 个回答

直接按文件md5作为文件名吧,重名的几率忽略不计

嗯,我的说法和楼上的一致,不过稍有区别,这也是我们对第三方图床采取的办法,贴段代码理解下把

$img_id = 新建一张图片表,只有自增ID及时间戳就行,img_id 为自增ID,你每次插时间戳到表,根绝pdo返回的自增ID来获得这个ID

然后用户传了哪些图片与用户的个人表里绑定外键,比如 1,2,3,4,5这几个标示都是它传的图片,如果并发非常高您可以暂存redis中然后定时脚本入库,随便解决千万级并发,无需队列需求

getRelPath(md5($img_id . 加密盐));

//根据当前时间戳拼接出图片路径
function getRelPath($time)
{
    $relativePath = FALSE;
    if(strlen($hashStr) == 32) {
        $relativePath = substr($hashStr, 0, 2) . "/" . substr($hashStr, 2, 2) . "/" . substr($hashStr, 4, 2) . "/" . substr($hashStr, 6);
    }
    return $relativePath;
}

然后获取的时候也照这个规则就能找到这个用户传的哪些图片啦,拼接图片记得加上后缀哦,其实不加后缀浏览器也能帮您识别的哈

哎,我也来po下我们现在在用的命名方法:<业务类型>/<年><月>/<日><时><分><秒><随机数>.<后缀名>
其中随机数采用下面算法:

public static function quickRandomString($length = 4)
{
    return substr(str_shuffle(str_repeat('0123456789abcdefghijklmnopqrstuvwxyz', $length)), 0, $length);
}

一般不会重复,为了防止同一秒内真的发生了quickRandomString生成的随机字符串重复的事情,我在分配文件名后会再用is_file检测下这个文件是否真的存在,存在的话,就再随机一次。如果3次随机都还重复,对不起,请重新传下吧。。。(目前没有遇到这样衰的用户)

p.s. 随机数的长度目前暂定4,如果真的每秒上传用户比较多,冲突比较多,改大一点就好了。

最终生成的文件名: /uploads/product/20170320/182111ap2n.jpg

function get_uuid(){
    $charid = strtoupper(md5(uniqid(mt_rand(), true)));
    $uuid = substr($charid, 0, 8).substr($charid, 8, 4).substr($charid,12, 4).substr($charid,16, 4).substr($charid,20,12);
    return strtolower($uuid);
}

使用这个函数去生成名字

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题