命令行cURL与引用包装URL工作,PHP cURL没有

时间:2014-10-08 16:07:32

标签: php curl amazon-s3

所以,我有一个我要下载的Amazon S3编码的URL。如果我在没有引号的情况下传递URL,我会从S3获得403 Forbidden响应。

curl -O https://zencoder-temp-storage-us-east-1.s3.amazonaws.com/t/20141008/413f96bd17a210c0cfe2997d83a4782c/Nerve_Flossing_Highly_Irratible_Radial_Nerve_Wartenburgs_Syndrome-thumb.jpg?AWSAccessKeyId=AKIAI456JQ76GBU7FECA&Signature=Sd18YXJIMvLqeRFZYCzDNYdpg7U%3D&Expires=1412866120

但是,只需将其包装在引号中,就可以从命令行中运行得很好:

curl -O "https://zencoder-temp-storage-us-east-1.s3.amazonaws.com/t/20141008/413f96bd17a210c0cfe2997d83a4782c/Nerve_Flossing_Highly_Irratible_Radial_Nerve_Wartenburgs_Syndrome-thumb.jpg?AWSAccessKeyId=AKIAI456JQ76GBU7FECA&Signature=Sd18YXJIMvLqeRFZYCzDNYdpg7U%3D&Expires=1412866120"

但是......当我尝试在PHP中实现它时,我最终保存了一个0字节的文件。

$curl = curl_init("'".$url."'");
$fp = fopen($filepath, "w");
curl_setopt($curl, CURLOPT_FILE, $fp);
curl_exec ($curl);
curl_close ($curl);
fclose($fp);

有没有办法用PHP做到这一点,我错过了?

编辑:提供实际的S3网址以便于测试。

3 个答案:

答案 0 :(得分:0)

看起来这不是引号。在这种情况下,行情绝对不重要。

看起来SSL证书有问题。我看你SSL证书不好。甚至,这是非常糟糕的。

您需要关闭验证:

curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);

<强>更新

这段代码可以解决问题:

$curl = curl_init('https://some.amazon.bucket.s3.amazonaws.com/o/123456/582305890298509238/my-video.mp4?AWSAccessKeyId=RANDOMKEYHERE&Signature=SIG&Expires=1412805904');
$fp = fopen(getcwd() . '/1.txt', "w");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
fwrite($fp, curl_exec($curl));
fclose($fp);
curl_close($curl);

我已经检查了这个

我仍然认为您的主要问题是SSL证书......

顺便提一下文件内容是:

<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>InvalidAccessKeyId</Code><Message>The AWS Access Key Id you provided does not exist in our records.</Message><RequestId>6DCACEEE9E886AF1</RequestId><HostId>JPHAbX6+Ql34/6Yvso0vofODswNtZvwPluJj3R6XBBsSkq0hjQ9cy/Aj6e73EOQt</HostId><AWSAccessKeyId>RANDOMKEYHERE</AWSAccessKeyId></Error>

答案 1 :(得分:0)

PHP curl只是期待一个参数。当您在命令行上添加引号时,您断言引号之间的任何内容都是您尝试传递给命令的特定参数。大多数命令行命令以这种方式工作。例如,如果要在命令行中移动文件,可以在引号中添加路径:

mv foo.txt "/home/bar/foo.txt"

这适用于复杂的参数(例如URL),名称中带空格的文件等

至于PHP,curl函数只是期望一个参数,它将在内部进行正确的转义。因此,当您在curl PHP命令中添加引号时,实际上是要求PHP加载此URL:

'https://some.amazon.bucket.s3.amazonaws.com/o/123456/582305890298509238/my-video.mp4?AWSAccessKeyId=RANDOMKEYHERE&Signature=SIG&Expires=1412805904'

相反:

https://some.amazon.bucket.s3.amazonaws.com/o/123456/582305890298509238/my-video.mp4?AWSAccessKeyId=RANDOMKEYHERE&Signature=SIG&Expires=1412805904

您提到不使用引号在命令行卷曲中不起作用。您是否尝试在PHP中添加引号?我猜这是可行的。

另一件令人厌倦的事情是你的S3存储桶的权限。您尝试从S3加载的文件可能没有正确的访问权限,允许PHP或您的Web服务器访问它。这将触发403错误。

答案 2 :(得分:-1)

你的网址包含各种特殊字符,并且整个字符串都放在一个字符上,以便我们使用双引号。