Few days ago I wanted to write a small PHP script to backup (upload) some files in Amazon S3. And because Amazon just released last month a new version of their SDK, AWS SDK for PHP 2 I decided to use this one.
I also choose to use Console component from Symfony2 and Composer to install all the dependencies.
In the root folder of my project I downloaded and installed composer, like this:
curl -s "http://getcomposer.org/installer" | php
In composer.json file I added this dependencies:
{ "require": { "aws/aws-sdk-php": "*", "monolog/monolog": "1.0.*", "symfony/class-loader": "2.1.3", "symfony/console": "2.1.3", "symfony/yaml": "2.1.3", "doctrine/common": "2.3.0", "symfony/finder": "2.1.4" }, "autoload": { "psr-0": { "Razvan": "src/" } } }
and after this I ran:
php composer.phar install
After runing this command, you will see in the project folder, a directory called vendor where are installed all the dependencies.
After that I created on the same level with vendor a folder called src and inside this one another folder called Razvan.
mkdir -p src/Razvan
inside the Razvan folder I put my BackupCommand.php
Below is a part of the code:
<?php namespace Razvan; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Yaml\Yaml; use Symfony\Component\Finder\Finder; use Aws\S3\S3Client; use Aws\S3\Enum\CannedAcl; use Aws\S3\Exception\S3Exception; /** * BackupCommand * eg: usage for upload: * php sync.php s3 /path/to/folder/ upload --relative * * @author razvan tudorica */ class BackupCommand extends Command { private $s3; protected function configure() { //... get the configuration for s3 $this ->setName('s3') ->setDescription('Syncronize Amazon S3 folder with the local folder') ->addArgument('localFolder', InputArgument::REQUIRED, 'Local folder FULL path') ->addArgument('action', InputArgument::REQUIRED, 'upload (or download)') ->addArgument('bucket', InputArgument::OPTIONAL, 'The bucket name', $this->bucket) ->addArgument('s3Folder', InputArgument::OPTIONAL, 'Remote S3 folder path') ->addOption('relative', null, InputOption::VALUE_NONE, 'If set, we will use relative path in the bucket') ; $conf = array( 'key'=>'YOURKEY', 'secret' => 'YOURSECRET', 'region' => 'us-east-1' //or your bucket's region ); $this->s3 = S3Client::factory($conf); } protected function execute(InputInterface $input, OutputInterface $output) { $action = $input->getArgument('action'); $localFolder = $this->input->getArgument('localFolder'); $bucket = $this->input->getArgument('bucket'); //check if input the parameters are correct //... $finder = new Finder(); $finder->files()->in($localFolder); $finder->files()->followLinks(); foreach ($finder as $file) { //some extra logic for setting the key //... $key = $startFolder . DIRECTORY_SEPARATOR . $file->getRelativePathname(); $this->output->writeln($key); try { $this->s3->putObject(array( 'Bucket' => $bucket, 'Key' => $key, 'Body' => fopen($file->getRealpath(), 'r'), 'ACL' => CannedAcl::PUBLIC_READ )); } catch (S3Exception $e) { $this->output->writeln("The file was not uploaded: " . $e->getMessage()); } } }
And now we have to call this command. For this, in the root folder of the project I created another small script called backup.php with this content:
#!/usr/bin/env php <?php require_once __DIR__.'/vendor/autoload.php'; use Razvan\BackupCommand; use Symfony\Component\Console\Application; $command = new BackupCommand(); $application = new Application(); $application->add($command); $application->run();
Now, we can run it from the console, with:
php sync.php s3 /home/razvan/mypictures
Based on this skeleton, I’m working for a more complex syncronization script between Amazon S3 and a local folder. You can find the code on GitHub.
Disclaimer:
It is possible the tutorial above to not be very complete and accurate.
The code it’s not optimized at all (eg: if you have a big amount of files or very big files).
This might interest you:
http://docs.aws.amazon.com/aws-sdk-php-2/guide/latest/service-s3.html#up…