PHP: Get file extension not working on uploads to S3

后端 未结 12 647
我寻月下人不归
我寻月下人不归 2020-12-06 17:49

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

12条回答
  •  粉色の甜心
    2020-12-06 18:30

    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,

    1. add a fully qualified URL to a new php script file you're going to write.
    2. the php script wil get the bucket and key passed to it
    3. Create the new filename from the "key"
    4. use the function "public static function copyObject($srcBucket, $srcUri, $bucket, $uri)" to copy the uploaded file to the new name
    5. then delete the original (using deleteObject($bucket, $uri))
    6. then redirect the user to where you want to send them

    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:

    1. have your "final" bucket
    2. for each upload, create a temporary bucket (that's 1c per 1000 buckets, if you're worried on costs)
    3. upload to temporary bucket
    4. create random name, check if does not exist in final bucket (that 1c per 1000 checks)
    5. copy file to final bucket (with new name)
    6. delete uploaded file as well as the bucket.
    7. periodically clean up buckets where the file uploads were not complete.

提交回复
热议问题