2014-04-02 39 views
1

雖然同步與s3client目錄PHP SDK完美的作品PHP:同步數據與Amazon S3

$s3client->uploadDirectory('/local/directory', 'my-bucket'); 

我仍然需要s3cmd --delete-刪除功能刪除存在於桶,而不是無與倫比的文件在源目錄中。

裁判:http://blogs.aws.amazon.com/php/post/Tx2W9JAA7RXVOXA/Syncing-Data-with-Amazon-S3

+0

爲什麼不先清空你的存儲桶並同步數據?按照這種方式,它會自動保持一致,如你所需。 – Rikesh

+0

@Rikesh,因爲有用戶/機器人連接到存儲桶和刪除目錄會產生很多錯誤 – gadelkareem

+1

好吧,我知道了我猜這是目前由PHP S3 SDK提供的,但我想你需要做一些變通。這[博客](http://s3tools.org/s3cmd-sync)可能會對您有所幫助。 – Rikesh

回答

0
  1. 使現有的文件和它們的md5sum值
  2. 列表獲取所有的S3的對象
  3. 比較md5s和轉讓,如果不同
  4. 刪除任何「遺留下來的'( - 刪除)文件

    function syncS3($bucket, $prefix, $targetDir) 
    { 
        if (!is_dir($targetDir)) { 
         mkdir($targetDir, 0755, true); 
        } 
    
        $localFileM5Sums = getMd5ForFilesInDir($targetDir); 
        $s3Objects  = $this->s3Client->listObjects(['Bucket' => $bucket, 'Prefix' => $prefix]); 
    
        foreach ($s3Objects['Contents'] as $contents) { 
         $s3Key = $contents['Key']; 
         if (substr($s3Key, -1, 1) == '/') { // is a 'directory' 
          continue; // skip 
         } 
    
         $saveAs = $targetDir . DIRECTORY_SEPARATOR . $s3Key; 
         if (isset($localFileM5Sums[$saveAs])) { // if we have local copy 
          $localMd5 = $localFileM5Sums[$saveAs]; 
          unset($localFileM5Sums[$saveAs]); // remove so we don't try to delete it later 
          if ($localMd5 === trim($contents['ETag'], '"')) { // and md5sumMatches 
           continue; // don't transfer 
          } 
         } 
    
         // transfer it 
         if (!is_dir(dirname($saveAs))) { 
          mkdir(dirname($saveAs), 0755, true); 
         } 
         $this->s3Client->getObject([ 
          'Bucket' => $bucket, 
          'Key' => $s3Key, 
          'SaveAs' => $saveAs 
         ]); 
        } 
    
        // remove any missing files 
        foreach ($localFileM5Sums as $fileName => $md5sum) { 
         unlink($fileName); 
        } 
    } 
    
    
    function getMd5ForFilesInDir($targetDir) 
    { 
        $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($targetDir)); 
        $files = []; 
        foreach ($iterator as $file) { 
         if (!$file->isDir()) 
          $files[$file->getPathname()] = md5_file($file->getPathname()); 
        } 
        return $files; 
    }