cURL在MS Windows上上传文件到远程服务器

5

当我使用Linux并尝试使用此脚本上传文件到远程服务器时,一切正常。但是如果我使用Windows,则脚本无法正常工作。 脚本:

$url="http://site.com/upload.php";
$post=array('image'=>'@'.getcwd().'images/image.jpg');
$this->ch=curl_init();
curl_setopt($this->ch, CURLOPT_URL, $url);
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($this->ch, CURLOPT_TIMEOUT, 30);
curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($this->ch, CURLOPT_POST, 1);
curl_setopt($this->ch, CURLOPT_POSTFIELDS, $post);
$body = curl_exec($this->ch);
echo $body; // << on Windows empty result

我做错了什么?

PHP 5.3

在Windows 7中不起作用,在Ubuntu Linux 10.10中可以使用。


你的Windows服务器上的PHP安装中是否编译了cURL?请展示出现的错误信息。你可以通过phpinfo()脚本检查安装情况。 - Orbling
错误未显示。(error_reporting = on) - Dador
getcwd()函数返回的路径末尾没有斜杠,所以我缺少了那个,除此之外,在Windows上你不应该使用反斜杠而不是正斜杠吗? - Mark Bekkers
CURLOPT_VERBOSE: TRUE用于输出冗长信息。将输出写入到STDERR或使用CURLOPT_STDERR指定的文件中。参见http://php.net/manual/en/function.curl-setopt.php。 - Mark Bekkers
日志中的错误:*** 创建表单数据失败** - Dador
5个回答

4

如果您使用的是Windows系统,文件路径分隔符将是\而不是Linux风格的/

一个明显的尝试是

$post=array('image'=>'@'.getcwd().'images\image.jpg');

看看这是否有效。

如果您想使脚本可移植,以便在Windows或Linux上使用,您可以使用PHP预定义的常量 DIRECTORY_SEPARATOR

$post=array('image'=>'@'.getcwd().'images' . DIRECTORY_SEPARATOR .'image.jpg');

不错的回答。学到了一些新东西。 - Code Lღver

4

从理论上讲,您的代码不应在任何Unix或Windows上运行(我是指上传)。考虑一下您代码中的这部分:

'image'=>'@'.getcwd().'images/image.jpg'

在Windows中,getcwd()返回F:\Work\temp
在Linux中,它返回/root/work/temp

因此,您上面的代码将编译如下:

Windows:'image'=>'@F:\Work\tempimages/image.jpg'
Linux:'image'=>'@/root/work/tempimages/image.jpg'

由于您提到在Linux上可以工作,这意味着/root/work/tempimages/image.jpg在您的文件系统中以某种方式存在。

我的PHP版本:
Linux:PHP 5.1.6
Windows:PHP 5.3.2


1
是的,这是可观察的。很好的答案。 - Code Lღver

1

你应该尝试使用var_dump($body)来查看$body的真实内容。根据你配置cURL的方式,$body将包含服务器响应或失败时的false。使用echo无法区分空响应和false。可能请求已经成功发送,但服务器没有返回任何内容。

然而,正如其他人所说,你的文件路径似乎无效。getcwd()不会输出最后的/,你需要添加一个才能使代码正常工作。既然你说它在Linux上可以正常工作,即使缺少斜杠,我想知道它是如何找到你的文件的。

我建议你创建一个相对于正在运行的PHP脚本的文件路径,或提供绝对路径,不要依赖于getcwd(),因为它可能不会返回你期望的值。在系统之间,getcwd()的值是不可预测的,也不太可移植。

例如,如果你要POST的文件与你的PHP脚本位于同一文件夹中:

$post = array('image' => '@image.jpg');就足够了。如果需要,提供绝对路径:$post = array('image' => '@/home/youruser/yourdomain/image.jpg');

正如 Terence 所说,如果您需要您的代码在 Linux 和 Windows 间可移植,请考虑使用 PHP 预定义常量DIRECTORY_SEPARATOR

$url = "http://yoursite.com/upload.php";
// images\image.jpg on Windows images/image.jpg on Linux
$post = array('image' => '@images'.DIRECTORY_SEPARATOR.'image.jpg');
$this->ch = curl_init();
curl_setopt($this->ch, CURLOPT_URL, $url);
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($this->ch, CURLOPT_TIMEOUT, 30);
curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($this->ch, CURLOPT_POST, 1);
curl_setopt($this->ch, CURLOPT_POSTFIELDS, $post);
$body = curl_exec($this->ch);
var_dump($body);

getcwd() cURL

{{链接1:getcwd()}} {{链接2:cURL}}


1
如果使用xampp,请确保在php.ini配置文件中取消注释第952行,即:
如果该行是:
   ;extension=php_curl.dll

然后将其制作。
  extension=php_curl.dll

curl正常工作,但是出现了不同的错误。 - Code Lღver

1
我认为,更好的方法是:

$imgpath = implode(DIRECTORY_SEPARATOR, array(getcwd(), 'images', 'image.jpg'));
$post = array('image'=>'@'.$imgpath);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接