开发者

Problem with sprintf error when using S3->copyObject() and filenames with % in them

开发者 https://www.devze.com 2023-01-08 21:40 出处:网络
I am using PHP S3.PHP class to manage files on Amazon S3. I use the copyObject() function to copy files in my S3 bucket. All works great until I meet filenames that need to be urlencoded (I urlencode

I am using PHP S3.PHP class to manage files on Amazon S3. I use the copyObject() function to copy files in my S3 bucket. All works great until I meet filenames that need to be urlencoded (I urlencode everything anyway). When a filename ends up with % characters in it the copyObject() function spits the dummy.

for example - the filename 63037_Copy%287%29ofDSC_1337.JPG throws the following error when passed to copyObject() -

Warning:  sprintf() [<a href='function.sprintf'>function.sprintf</a>]: Too few arguments in ..... S3.php on line 477

Here's the copyObject function line 477

public static function copyObject($srcBucket, $srcUri, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array()) {
    $rest = new S3Request('PUT', $bucket, $uri);
    $rest->setHeader('Content-Length', 0);
    foreach ($requestHeaders as $h => $v) $rest->setHeader($h, $v);
    foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v);
    $rest->setAmzHeader('x-amz-acl', $acl);
    $rest->setAmzHeader('x-amz-copy-source', sprintf('/%s/%s', $srcBucket, $srcUri));
    if (sizeof($requestHeaders) > 0 || sizeof($metaHeaders) > 0)
        $rest->setAmzHeader('x-amz-metadata-directive', 'REPLACE');
    $rest = $rest->getResponse();
    if ($rest->error === false && $rest->code !== 200)
        $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
    if ($rest->error !== false) {
-------------------------------------------- LINE 477 ----------------------------


        **trigger_error(sprintf("S3::copyObject({$srcBucket}, {$srcUri}, {$bucket}, {$uri}): [%s] %s",
        $rest->error['code'], $rest->error['message']), E_USER_WARNING);**


-------------------------------------------- LINE 477 ----------------------------

        return false;
    }
    return isset($rest->body->LastModified, $rest->body->ETag) ? array(
        'time' => strtotime((string)$rest->body->LastModified),
        'hash' => substr((string)$rest->body->ETag, 1, -1)
    ) : false;
}

Has anyone come across this before? There is absolutely no problem when using filenames which don't change when urlencoded, and Ive already tried removing all whitespace from filenames but wont be able to catch all characters, like brackets which is the problem in the example here. And I dont want to go down that road anyway as I want to keep the filename开发者_JAVA百科s as close to the original as possible.

thanks guys


Redo the line this way:

trigger_error("S3::copyObject({$srcBucket}, {$srcUri}, {$bucket}, {$uri}): ". sprintf("[%s] %s",
        $rest->error['code'], $rest->error['message']), E_USER_WARNING);

%'s in the first parameter to sprintf are identified as the placeholders for values. Because your filenames are first inserted in the string and that string is then passed to sprintf(), sprintf() mistakenly interprets the %'s in the file names as placeholders.

0

精彩评论

暂无评论...
验证码 换一张
取 消