Romain
Romain

Reputation: 455

Create & zip & Download an S3 folder/multiple-files with AWS SDK PHP

I'm willing to create a php function, trigger in js, that can :

I'm able to download a single file with the getObject method from this example However, I can't find any informations in order to download multiple file and Zip it.

I tried the downloadBucket method, however it download all files inside my project architecture and not as a zip file. Here is my code:

<?php


// AWS Info + Connection
$IAM_KEY = 'XXXXX';
$IAM_SECRET = 'XXXXX';
$region = 'XXXXX';  

require '../../vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;

$FolderToDownload="FolderToDownload";


// Connection OK
$s3 = S3Client::factory(
    array(
        'credentials' => array(
            'key' => $IAM_KEY,
            'secret' => $IAM_SECRET
        ),
        'version' => 'latest',
        'region'  => $region
    )
);

try {

    $bucketName = 'XXXXX';
    $destination = 'NeedAZipFileNotAFolderPath';
    $options = array('debug'=>true);

    // ADD All Files into the folder: NeedAZipFileNotAFolderPath/Files1.png...Files12.png...
    $s3->downloadBucket($destination,$bucketName,$FolderToDownload,$options);
    
    // Looking for a zip file that can be downloaded
    // Can I use downloadBucket? Is there a better way to do it?
    // if needed I can create an array of all files (paths) that needs to be added to the zip file & dl


} catch (S3Exception $e) {
    echo $e->getMessage() . PHP_EOL;
    }


?>

If some one can help, would be nice. Thanks

Upvotes: 5

Views: 11769

Answers (1)

Gray Fox
Gray Fox

Reputation: 96

You can use ZipArchive, list the objects from a prefix (the bucket's folder). In the case, I also use 'registerStreamWrapper' to get the keys and added to the created zip file.

Something like that:

<?php

require '/path/to/sdk-or-autoloader';

$s3 = Aws\S3\S3Client::factory(/* sdk config */);
$s3->registerStreamWrapper();

$zip = new ZipArchive;
$zip->open('/path/to/zip-you-are-creating.zip', ZipArchive::CREATE);

$bucket = 'your-bucket';
$prefix = 'your-prefix-folder'; // ex.: 'image/test/folder/'
$objects = $s3->getIterator('ListObjects', array(
    'Bucket' => $bucket,
    'Prefix' => $prefix
));

foreach ($objects as $object) {
    $contents = file_get_contents("s3://{$bucket}/{$object['Key']}"); // get file
    $zip->addFromString($object['Key'], $contents); // add file contents in zip
}

$zip->close();

// Download de zip file
header("Content-Description: File Transfer"); 
header("Content-Type: application/octet-stream"); 
header("Content-Disposition: attachment; filename=\"/path/to/zip-you-are-creating.zip\""); 
readfile ('/path/to/zip-you-are-creating.zip');
    
?>

You can also delete the zip file after the download, if you prefer.

Must work in most of cases, but I don't want to save the file in the server, but I don't see how I can download multiple objects directly from the AWS S3 bucket by the browser without saving a file in my server. If anyone know, please share with us.

Upvotes: 8

Related Questions