本文介绍了PHP:获取文件扩展名不工作的上传到S3的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用亚马逊S3 API的文件上传,我每一次我上传更改文件的名称。

因此​​,例如:

Dog.png> 3Sf5f.png

现在我得到的随机部分工作作为这样的:

 函数rand_string($长度){
            $字符=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789;

            $大小=的strlen($字符);
            为($ i = 0; $ I< $长度; $ I ++){
                。$海峡= $字符[兰特(0,$大小 -  1)]。
            }

            返回$海峡;
        }
 

所以我设置random_string的名称参数作为这样的:

  $ params->键= rand_string(5);
 

现在我的问题是,这将不会显示任何扩展。因此,该文件将上传来代替 3Sf5f.png 3Sf5f

变量$文件名给了我与它的扩展名的文件的全名。

如果我用 $ params->键= rand_string(5)'$ {文件名}; 我得到的:

  3Sf5fDog.png
 

于是,我就找回$文件扩展名,并将其应用。我想30多方法,没有任何积极的。

例如我试过$ PATH_INFO(),我试过SUBSTR(strrchr($ FILE_NAME,),1'。');任何更多。所有这些给我任何 3Sf5fDog.png 或只是 3Sf5f

什么我想举个例子:

  //由于@jcinacio指出。更改为:
//
// $ FILE_NAME =$ {文件名};
//
$ FILE_NAME ='$ {文件名}//是不对的,因为'..'不评价

$ params->键= rand_string(5)$ FILE_NAME。
=
3Sf5fDog.png
 

  $ FILE_NAME = SUBSTR(strrchr('$ {文件名},),1'。');

$ params->键= rand_string(5)$ FILE_NAME。
=
3Sf5f
 

  $文件名=example.png//如果我宣布我自己的文件名,它的工作原理。
$ FILE_NAME = SUBSTR(strrchr('$ {文件名},),1'。');

$ params->键= rand_string(5)$ FILE_NAME。
=
3Sf5f.png
 

整个类文件: http://pastebin.com/QAwJphmW (没有其他文件,为整个脚本)

我是我做错了吗?这真是令人沮丧。

解决方案

变量$文件名(因此$ {文件名})的范围并不在你的code(行号1053线的基础上生从引擎收录粘贴)。

所以,不管你做什么,你永远也找不到一个不存在的变量的扩展。


和我终于摸索出自己在做什么。我presume这是一个扩展PHP:上传之前,重命名文件

答案很简单:你不能做到这一点,你envisage.Why - 把'$文件名'不解析在创建该URL的时间,但变量传递给Amazon S3和处理存在。

解决方案

所以,唯一的选择我能想到的是有使用successRedirect参数指向另一个URL。该URL将收到斗,并从亚马逊的钥匙作为查询参数(http://doc.s3.amazonaws.com/proposals/post.html#Dealing_with_Success)。点到重命名在Amazon S3上的文件(复印件+删除)一个PHP脚本,然后将用户重定向到另一个成功的画面。

因此​​,

在code,34行,

  1. 添加一个完全合格的URL你去一个新的PHP脚本文件写。
  2. PHP脚本西港岛线得到传递给它的桶和关键
  3. 从钥匙创建新的文件名
  4. 使用功能的公共静态功能copyObject($ srcBucket,$ srcUri,$桶,$ URI)复制上传文件以新的名称
  5. 然后删除原始(使用deleteObject($桶,$ URI))
  6. 然后将用户重定向到要送他们

这会做你想要什么。


在响应您的评论:这是唯一的方法? - 怎么样的成本,因为每个请求亚马逊费

删除请求都是免费的。在相同的铲斗移动时,没有数据传送费用(或甚至在相同的区域)。因此,该解决方案(这是没有你转移到中间服务器,重命名和上载的唯一途径)双打的上载从1C的费用为1000上传至每1000上传2C。这是我花10分钟@ $ 200 /小时才找到了这一点,并作出回应= $ 33 = 1666666上传!成本苍白有点当你做数学:)

与其他解决方案进行比较:做一个职位,一个Web服务器,重命名文件,然后上载从Web服务器:您从clinet tdirectly将所有的带宽,以自己 - 的两倍。这还引入了风险和增加的可能故障点。


在回答是行不通的。我对你上传然后旧的被删除的文件

我会assusme这不是一个问题,因为你上传的文件,然后在一两秒钟将其重命名。但是如果你想OT出示担保的每个文件被上传,那么你需要做很多超过反正创建一个随机文件名:

  1. 有你的最终斗
  2. 在每个上传,创建一个临时桶(也就是每1000桶1C,如果你对成本很担心)
  3. 上传到临时斗
  4. 创建随机点名,检查是否没有在最后的斗存在(每1000将检查1C)
  5. 将文件复制到最终桶(新名称)
  6. 删除上传的文件,以及桶。
  7. 在定期清理桶所在的文件上传不完整。

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.

解决方案

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 towrite.
  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 functioncopyObject($srcBucket, $srcUri, $bucket, $uri)" to copy the uploadedfile 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.

这篇关于PHP:获取文件扩展名不工作的上传到S3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-27 14:57