如何使用带有OOP的cURL从服务器下载二进制响应的文件?

时间:2017-02-08 00:28:39

标签: php json oop curl

现在已经持续了一段时间,无法弄清楚我错过了什么......

我写了一个简单的类来使用cURL作为OOP。它适用于所有API请求,但下载文件除外。

使用POST方法以JSON格式将请求发送到服务器。响应也是JSON。下载API是唯一一个,它没有在JSON中响应,而是直接以二进制形式发送文件。这个似乎不适合我的小班。

请您查看下面的代码并提出建议吗?非常感谢!

curlClass.php - >包含cURL方法的类文件。

<?php

class curlClass {
    private $_cookie_jar;

    public function login($email, $password, $url){
        $ch = curl_init($url);

        curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
        curl_setopt($ch, CURLOPT_USERPWD, "$email:$password");
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        $this->_cookie_jar = tempnam('folder','cookie_');
        curl_setopt($ch, CURLOPT_COOKIEJAR, $this->_cookie_jar);
        $_SESSION['cookieFile'] = $this->_cookie_jar;

        $page = curl_exec($ch);

        curl_close($ch);

        return strlen($page);
    }

    public function postApi($post_data, $cookie_j, $url){

        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
        //curl_setopt($ch, CURLOPT_HEADER, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_j);
        $page = curl_exec($ch);
        curl_close($ch);

        $json = json_decode($page);

        return json_encode($json, JSON_PRETTY_PRINT);
    }

    public function downloadFile($post_data, $cookie_j, $url){

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_VERBOSE, 1);
        curl_setopt($ch, CURLOPT_HEADER, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
        curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_j);
        curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);

        $response = curl_exec($ch);

        // Then, after your curl_exec call:
        $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
        $header = substr($response, 0, $header_size);
        $body = substr($response, $header_size);

        curl_close($ch);

        return json_encode($response, JSON_PRETTY_PRINT); 
        exit();
    }
}

?>

index.php - &gt;这就是我称之为类及其功能的地方。

<?php
    require_once 'core/init.php';

    $curl = new Curl();

    if($curl->login('username', 'password', 'https://example.com/api' > 0){

        $data = array('someRequest', 24);

        $data_string = json_encode($data);

        echo $curl->downloadFile($data_string, $_SESSION['cookieFile'], 'https://example.com/api');

    }
?>

但是,如果我将download.php用作单个文件,它将按预期工作。问题是我需要将登录凭据传递给它。只有我可以使用该类,然后我可以登录一次并重新使用cookie进行进一步的查询..

的download.php

<?php
    require_once 'core/init.php';

    $login = 'username';
    $password = 'password';
    $url = 'https://example.com/api';
    $data = array("someRequest", 25);

    $data_string = json_encode($data);

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,$url);
    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    curl_setopt($ch, CURLOPT_USERPWD, "$login:$password");
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);


    $file = curl_exec($ch);

    $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
    $header = substr($file, 0, $header_size);
    $body = substr($file, $header_size);
    $header_items = explode("\n", $header);

    curl_close($ch);

    echo '<pre>'.print_r($file, true).'</pre>';
    exit();
?>

提前感谢您的建议!

1 个答案:

答案 0 :(得分:1)

downloadFile()功能中,return json_encode($response, JSON_PRETTY_PRINT);似乎不正确。

这会将响应编码为字符串,如果要使用它,则需要再次对其进行解码。

似乎最合适的做法是从此函数返回一个字符串(内容)而不是JSON字符串。 return $response;就足够了。