I am using the Amazon S3 API to upload files and I am changing the name of the file each time I upload.
So for example:
Dog.png > 3Sf5f.png
Now I got the random part working as such:
function rand_string( $length ) {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$size = strlen( $chars );
for( $i = 0; $i < $length; $i++ ) {
$str .= $chars[ rand( 0, $size - 1 ) ];
}
return $str;
}
So I set the random_string to the name parameter as such:
$params->key = rand_string(5);
Now my problem is that this wont show any extension. So the file will upload as 3Sf5f
instead of 3Sf5f.png
.
The variable $filename gives me the full name of the file with its extension.
If I use $params->key = rand_string(5).'${filename}';
I get:
3Sf5fDog.png
So I tried to retrieve the $filename extension and apply it. I tried more than 30 methods without any positive one.
For example I tried the $path_info(), I tried substr(strrchr($file_name,'.'),1); any many more. All of them give me either 3Sf5fDog.png
or just 3Sf5f
.
An example of what I tried:
// As @jcinacio pointed out. Change this to:
//
// $file_name = "${filename}";
//
$file_name = '${filename}' // Is is wrong, since '..' does not evaluate
$params->key = rand_string(5).$file_name;
=
3Sf5fDog.png
.
$file_name = substr(strrchr('${filename}', '.'), 1);
$params->key = rand_string(5).$file_name;
=
3Sf5f
.
$filename = "example.png" // If I declare my own the filename it works.
$file_name = substr(strrchr('${filename}', '.'), 1);
$params->key = rand_string(5).$file_name;
=
3Sf5f.png
The entire class file: http://pastebin.com/QAwJphmW (there are no other files for the entire script).
What I'm I doing wrong? This is really frustrating.
S3 doesn't run any sort of CGI script (PHP, Perl, Ruby, etc). Think of it as a static html and image repository. If you want to host your PHP application on AWS, consider using AWS Beanstalk.
Valid formats are CSV , TSV , CLF , ELF , and JSON . The default value is CSV . delimiter – (Optional) Specify the file field delimiter.
In AWS Explorer, expand the Amazon S3 node, and double-click a bucket or open the context (right-click) menu for the bucket and choose Browse. In the Browse view of your bucket, choose Upload File or Upload Folder. In the File-Open dialog box, navigate to the files to upload, choose them, and then choose Open.
The variable $filename (and thus "${filename}") is NOT IN SCOPE at line 1053 of your code (line numbering based on raw paste from pastebin).
So, no matter what you do, you'll never find the extension of a variable that does not exist.
And I've finally worked out what you're doing. I presume this is an extension of PHP: Rename file before upload
Simple answer: you can't do it as you envisage.Why - the '$filename' is not parsed at the time that URL is created, but the variable is passed to Amazon S3 and handled there.
The solution
So, the only option I can think of is to have use the "successRedirect" parameter to point to another URL. That URL will receive the "bucket" and "key" as query parameters from Amazon (http://doc.s3.amazonaws.com/proposals/post.html#Dealing_with_Success). Point that to a PHP script that renames the file on Amazon S3 (copy + delete), then redirects the user to another success screen.
So,
in your code, line 34,
That will do exactly what you want.
In response to your comments "Is this the only way - what about the costs as Amazon charge per request?"
Delete requests are free. No data transfer costs when moving on the same bucket (or even in the same region). So this solution (which is the only way without you transferring to an intermediate server, renaming and uploading) it doubles the cost of upload a from 1c per 1000 uploads to 2c per 1000 uploads. It's taken me 10 minutes @ $200/hour to find that out and respond = $33 = 1,666,666 uploads! Costs pale a bit when you do the maths :)
Compare with the other solution: do a post to an webserver, rename the file and then upload from the webserver: you move all the bandwidth from the clinet tdirectly to yourself - twice. And this also introduces risk and increased possible failure points.
In response to "Doesn't work. I you upload a file then the old one gets deleted"
I would assusme this is not a problem as you upload a file and then rename it within a second or two. But if you want ot gurantee each file gets uploaded, then you need to do a lot more than create a random filename anyway:
$fileSplit = explode('.',$filename);
$extension = '.'.$fileSplit[count($fileSplit) - 1];
This explode() divides up the file name into an array with periods as delimiters, and then grabs the last piece of the array (incase a file name is foo.bar.jpg), and puts a period in front of it. This should get you the desired extension to append it to the rand_string(5).
$params->key = rand_string(5).$extension;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With