Php 使用S3时出现sprintf错误问题->;copyObject()和其中包含%的文件名

Php 使用S3时出现sprintf错误问题->;copyObject()和其中包含%的文件名,php,copy,amazon-s3,urlencode,printf,Php,Copy,Amazon S3,Urlencode,Printf,我正在使用PHPS3.PHP类来管理AmazonS3上的文件。我使用copyObject()函数复制S3存储桶中的文件。在遇到需要URL编码的文件名之前,所有这些都非常有效(无论如何,我都会对所有内容进行URL编码)。当文件名以%个字符结尾时,copyObject()函数将抛出伪文件 例如,文件名63037_Copy%287%29ofDSC_1337.JPG在传递到copyObject()时引发以下错误- 以前有人见过这个吗?使用URL编码时不会更改的文件名绝对没有问题,而且我已经尝试从文件名中

我正在使用PHPS3.PHP类来管理AmazonS3上的文件。我使用copyObject()函数复制S3存储桶中的文件。在遇到需要URL编码的文件名之前,所有这些都非常有效(无论如何,我都会对所有内容进行URL编码)。当文件名以%个字符结尾时,copyObject()函数将抛出伪文件

例如,文件名63037_Copy%287%29ofDSC_1337.JPG在传递到copyObject()时引发以下错误-

以前有人见过这个吗?使用URL编码时不会更改的文件名绝对没有问题,而且我已经尝试从文件名中删除所有空白,但无法捕获所有字符,如括号,这是本例中的问题。我不想走这条路,因为我想保持文件名尽可能接近原始文件名


谢谢大家

用这种方式重做这一行:

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

%sprintf的第一个参数中的被标识为值的占位符。因为您的文件名首先插入到字符串中,然后该字符串被传递给sprintf(),sprintf()错误地将文件名中的%解释为占位符。

谢谢,这可能是正确的答案,但我在上传文件名时只是对其进行了str_替换,以避免这一问题。谢谢你的回复,问候。
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;
}
trigger_error("S3::copyObject({$srcBucket}, {$srcUri}, {$bucket}, {$uri}): ". sprintf("[%s] %s",
        $rest->error['code'], $rest->error['message']), E_USER_WARNING);