thinkphp5.1 批量上傳文件-生成重複文件名的問題

導讀

今天使用了 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();
        }    
    }
}
複製代碼

結束

相關文章
相關標籤/搜索