今天使用了 thinkphp 的圖片批量上傳發現 同時上傳三個文件的狀況下 只存儲了兩個文件缺失一個文件,調試發現 生成文件名時 生成出一樣的名字致使文件被覆蓋.php
視圖thinkphp
<form action="/index/index/upload" enctype="multipart/form-data" method="post">
<input type="file" name="image[]" /> <br>
<input type="file" name="image[]" /> <br>
<input type="file" name="image[]" /> <br>
<input type="submit" value="上傳" />
</form>
複製代碼
控制器框架
public function upload(){
// 獲取表單上傳文件
$files = request()->file('image');
foreach($files as $file){
// 移動到框架應用根目錄/uploads/ 目錄下
$info = $file->move( '../uploads');
if($info){
// 成功上傳後 獲取上傳信息
// 輸出 jpg
echo $info->getExtension();
// 輸出 42a79759f284b767dfcb2a0197904287.jpg
echo $info->getFilename();
}else{
// 上傳失敗獲取錯誤信息
echo $file->getError();
}
}
複製代碼
}函數
上述代碼在move 過程當中直接生成了文件名 , 看下是怎麼生成文件名的post
/thinkphp/library/think/File.php 自動 生成文件名的方法是autoBuildNameui
protected function autoBuildName()
{
if ($this->rule instanceof \Closure) {
$savename = call_user_func_array($this->rule, [$this]);
} else {
switch ($this->rule) {
case 'date':
$savename = date('Ymd') . DIRECTORY_SEPARATOR . md5(microtime(true));
break;
default:
if (in_array($this->rule, hash_algos())) {
$hash = $this->hash($this->rule);
$savename = substr($hash, 0, 2) . DIRECTORY_SEPARATOR . substr($hash, 2);
} elseif (is_callable($this->rule)) {
$savename = call_user_func($this->rule);
} else {
$savename = date('Ymd') . DIRECTORY_SEPARATOR . md5(microtime(true));
}
}
}
return $savename;
}
複製代碼
$this->rule 默認值 date 因此生成 文件名的是this
$savename = date('Ymd') . DIRECTORY_SEPARATOR . md5(microtime(true));
複製代碼
md5 加密 當前微秒浮點數加密
在循環的時候在同一時間調用了該方法因此生成了 一樣的文件名spa
生成文件名的規則能夠傳入回調, 本身實現一個 生成的回調函數調試
在項目根目錄的common.php 文件中 建立一個公共函數
if (!function_exists('autoBuild')) {
/**
* /*
* 自定義生成文件名生成規則
* thinkphp 框架採用微秒時間戳生成致使批量上傳時生成重複名稱
*
* @param $rule 加密方法
* @return string
*/
function autoBuild($rule='sha256'){
if (!in_array($rule, hash_algos())) {
$rule='md5';
}
$uuid=guid();
$hash=hash($rule, time().mt_rand(1000,9999).$uuid);
$savename = date('Ymd') . DIRECTORY_SEPARATOR . substr($hash, 2,36);
return $savename;
}
}
/**
* 生成惟一ID
*/
if (!function_exists('guid')) {
function guid()
{
if (function_exists('com_create_guid')) {
return com_create_guid();
} else {
mt_srand((double)microtime() * 10000);//optional for php 4.2.0 and up.
$charid = strtoupper(md5(uniqid(rand(), true)));
$hyphen = chr(45);// "-"
$uuid = chr(123)// "{"
. substr($charid, 0, 8) . $hyphen
. substr($charid, 8, 4) . $hyphen
. substr($charid, 12, 4) . $hyphen
. substr($charid, 16, 4) . $hyphen
. substr($charid, 20, 12)
. chr(125);// "}"
return $uuid;
}
}
}
複製代碼
public function upload(){
// 獲取表單上傳文件
$files = request()->file('image');
foreach($files as $file){
// 移動到框架應用根目錄/uploads/ 目錄下 使用 autoBuild 構建文件名
$info = $file->rule('autoBuild')->move( '../uploads');
if($info){
// 成功上傳後 獲取上傳信息
// 輸出 jpg
echo $info->getExtension();
// 輸出 42a79759f284b767dfcb2a0197904287.jpg
echo $info->getFilename();
}else{
// 上傳失敗獲取錯誤信息
echo $file->getError();
}
}
}
複製代碼