下载文件的PHP头导致字符串改变?

时间:2015-02-13 20:29:46

标签: php curl

我在尝试通过PHP将字符串下载到文件时遇到问题。

$start = explode('-', Requests::param('start'));
        $end = explode('-', Requests::param('end'));

        $dates = array(
            'start' => array(
                'year' => intval($start[0]),
                'month' => intval($start[1]),
                'day' => intval($start[2])
            ),
            'end' => array(
                'year' => intval($end[0]),
                'month' => intval($end[1]),
                'day' => intval($end[2])
            )
        );

        $dates_json = json_encode($dates);

        $ch = curl_init();
        curl_setopt($ch,CURLOPT_URL, $url);
        curl_setopt($ch,CURLOPT_POST, count($dates_json));
        curl_setopt($ch,CURLOPT_POSTFIELDS, $dates_json);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Content-Type: application/json'
        ));
        $result = curl_exec($ch);
        curl_close($ch);

        header('Content-Disposition: attachment; filename="activities.csv"');
        header('Content-Type: text/csv');
        header('Content-Length: ' . strlen($result));
        header('Connection: close');

        echo $result;

$result是CSV文件字符串。

它通过CURL请求就好了,如果我没有标题并记录它,它就像它应该的那样。

但是,只要我添加header个功能,我的$result字符串就会从CSV文件更改为单个",而且我不知道为什么。

如果我将其记录到我的错误文件中,它只会记录为1而不是",这也很奇怪。

设置的唯一其他标头是X-Powered-By: PHP/5.5.20,因此这里不应该有任何问题。

我该怎么做才能解决这个问题?

1 个答案:

答案 0 :(得分:0)

您的代码存在一些问题:

  • CURLOPT_POST

    $dates_json = json_encode($dates);
    ...
    curl_setopt($ch,CURLOPT_POST, count($dates_json));
    

    CURLOPT_POST是一个布尔选项。您应该将其设置为TRUE1。将它设置为计数毫无意义。

    但是,json_encode()的结果是string(或FALSE)。将count()应用于非arrayCountable的内容会导致1,因此它实际上会以迂回的方式运行。

  • CURLOPT_POSTFIELDS

    curl_setopt($ch,CURLOPT_POSTFIELDS, $dates_json);
    

    CURLOPT_POSTFIELDS选项需要urlencoded字符串或关联数组。你应该传递类似的东西:

    curl_setopt($ch,CURLOPT_POSTFIELDS, 'dates=' . rawurlencode ($dates_json));
    

    或:

    curl_setopt($ch,CURLOPT_POSTFIELDS, array ('dates' => $dates_json));
    

    或(作为例子):

    curl_setopt($ch,CURLOPT_POSTFIELDS, 
      array ('start' => Requests::param('start'),
             'end'   => Requests::param('end')));
    

    或其他一些键和值的组合,具体取决于目标脚本。在上面的示例中,脚本必须使用$_POST['dates']或最后一个示例$_POST['start']$_POST['end']检索值。

  • CURLOPT_HTTPHEADER

    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
      'Content-Type: application/json'
    ));
    

    这对于正常的POST请求毫无意义。我认为Curl会将Content-Type设置为application/x-www-form-urlencodedmultipart/form-data,具体取决于提供给CURLOPT_POSTFIELDS的值的形式。

  • curl_exec()

    $result = curl_exec($ch);
    ...
    echo $result;
    

    curl_exec()的默认行为是直接输出结果,然后返回TRUEFALSE。如果curl_exec()返回TRUE,则最终echo $result;将输出1

    如果您希望curl_exec()返回结果而不是TRUE,则需要致电curl_setopt (CURLOPT_RETURNTRANSFER, 1)

概要

总而言之,您的代码可能会像这样 ,具体取决于目标$url所期望的参数:

$ch = curl_init();
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, 1);
curl_setopt($ch,CURLOPT_POSTFIELDS, 'dates=' . rawurlencode ($dates_json));

if (!curl_exec($ch)) {
  // Error message
}
curl_close($ch);