在PHP中将curl的标准输出捕获到变量中

3

任务

从远程媒体处理服务器下载二进制文件到web服务器。

虽然成功了,但我无法捕获curl stdout输出

$result = shell_exec('curl -v http://domain.com/images/dir/dir/dir/file.jpg --user username:password -o /usr/www/htdocs/images/dir/dir/dir/file.jpg');

注意: 我尝试过使用PHP curl包装方法完成这个任务,但没有成功,部分原因是因为我从来没有使用PHP curl包装程序进行FTP下载。

问题 有人能解释一下如何捕获我正在运行的命令的输出,或者给出一个使用PHP curl包装程序的简单示例吗?

以下是我尝试过的内容,我卡壳的部分是如何将新文件放置在目标服务器上——错误的地方在于CURLOPT_FILE行。我不想创建一个存根文件、打开它,然后写入它。

$curl = curl_init();

curl_setopt($curl, CURLOPT_URL, $ftpserver.$file['directory'].$filename); #input
curl_setopt($curl, CURLOPT_FILE, $dest); #output
curl_setopt($curl, CURLOPT_USERPWD, "$user:$password");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($curl);

谢谢


你真的必须使用curl吗?你可以直接使用fopen打开URL。 - David Pfeffer
5个回答

3
根据PHP手册中的评论,在文件正确写入之前,必须确保关闭curl流和文件处理器。以下是示例(仅供查询):
<?php

$fh = fopen('/tmp/foo', 'w');
$ch = curl_init('http://example.com/foo');
curl_setopt($ch, CURLOPT_FILE, $fh);
curl_exec($ch);
curl_close($ch);

# at this point your file is not complete and corrupted

fclose($fh);

# now you can use your file;

read_file('/tmp/foo');

?>

此外,我认为使用CURLOPT_FILE和CURLOPT_RETURNTRANSFER的优缺点值得商榷。因为CURLOPT_RETURNTRANSFER告诉curl将获取的结果作为curl_exec()的结果返回。如果你只是将结果写入文件,则可能不需要这个选项。

我同意。那里不应该有这个。 - Slinky
你的辩论节省了我的时间。+1 - Terminal

0

$dest 需要通过文件资源打开

$dest = fopen("filename.ext", "w");

这对你有用吗?


可能会起作用,但我想避免创建存根文件然后写入它。我确定我的行“...CURLOPT_FILE”不正确,因为源机器上不存在该文件。 - Slinky

0
    /**
*Downloads a binary file into a string
*@param string $file URL's file 
*@param string $ref  Referer
*@return string $downloaded_binary string containing the binary file
*/
function download_file($file, $ref)
{
    $curl_obj = curl_init();    
    curl_setopt($curl_obj, CURLOPT_URL, $file);
    curl_setopt($curl_obj, CURLOPT_REFERER, $ref);
        curl_setopt($curl_obj, CURLOPT_BINARYTRANSFER, 1);
        curl_setopt($curl_obj, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($curl_obj, CURLOPT_MAXREDIRS, SPDR_MAX_REDIR);                           
    curl_setopt($curl_obj, CURLOPT_FOLLOWLOCATION, TRUE); //followlocation cannot be used when safe_mode/open_basedir are on
    curl_setopt($curl_obj, CURLOPT_SSL_VERIFYPEER, FALSE);               
        $downloaded_binary = curl_exec($curl_obj);    

        curl_close($curl_obj);
        return $downloaded_binary;
}

0

通过重定向标准输出,解决了这个问题:2>&1

所以这样做是有效的: $result = shell_exec('curl -v http://domain.com/images/dir/dir/dir/file.jpg --user username:password -o /usr/www/htdocs/images/dir/dir/dir/file.jpg 2>&1');

如果能够使用PHP curl包装器就太好了,但前提是不需要在源机器上打开存根文件并写入。curl命令行版本只需移动文件,非常整洁。如果有人知道如何使用PHP包装器来实现我正在尝试的操作,我很想看看你是如何做到的。


0

我认为实现这个的方法是使用ob_start()

ob_start();
curl_exec($curl);
$result = ob_get_clean();

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