【问题标题】:cURL not sending file to API CALLcURL 未将文件发送到 API CALL
【发布时间】:2013-02-01 12:47:40
【问题描述】:

我正在构建一个从 API 运行的移动站点,并且有一个 API CALL 处理程序类,它执行我从主函数文件运行的所有调用。

这里的问题是我的文件没有被发送到 API,它无法识别什么是文件并返回文件不存在错误。

注意:问题已解决,代码如下

代码如下:

表格

<form id="uploadPhoto" action="<?php uploadStreamPhoto(); ?>" method="post" enctype="multipart/form-data">
    <input type="file" name="streamPhotoUpload" id="streamPhotoUpload" />
    <input type="submit" name="streamPhotoUploadSubmit" id="streamPhotoUploadSubmit" value="Upload" />
</form>

上传功能

function uploadStreamPhoto()
{

    if(isset($_POST['streamPhotoUploadSubmit']))
    {

        $apiHandler = new APIHandler();
        $result = $apiHandler->uploadStreamPhoto($_FILES['streamPhotoUpload']['tmp_name']);
        $json = json_decode($result);
        var_dump($json);

        //header('Location: '.BASE_URL.'stream-upload-preview');

    }

}

处理方法

public function uploadStreamPhoto($file)
{

    $result = $this->request(API_URL_ADD_PHOTO, array(
    'accessToken' => $this->accessToken,
    'file' => "@$file;filename=".time().".jpg",
    'photoName' => time(),
    'albumName' => 'Stream'
    )); 

    return $result;

}

CURL 请求方法

/**
* Creates a curl request with the information passed in post fields
*
* @access private
* @param string $url
* @param array $postFields
* @return string
**/
private function request($url, $postFields = array())
{

    $curl = curl_init();

    //Check the SSL Matches the host
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);

    if($this->debug == true)
    {

        //Prevent curl from verifying the certificate
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);

    }

    //Set the URL to call
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_HEADER, 0);

    //Set the results to be returned
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

    //Set the curl request as a post
    curl_setopt($curl, CURLOPT_POST, 1); 

    //Set the post fields
    curl_setopt($curl, CURLOPT_POSTFIELDS, $postFields); 

    $result = curl_exec($curl);

    if($result === false)
    {

        $result = 'Curl error: '.curl_error($curl);

    }

    curl_close($curl);

    return $result;

}

【问题讨论】:

    标签: php file file-upload curl


    【解决方案1】:

    对于那些在 PHP 5.5 发布后结束的人,我的 2 美分。有两点值得一提:

    PHP 5.5 更改

    在 PHP 5.5 中引入了一个改变文件上传过程的新函数。 rfc:curl-file-uploads 描述得最好。因此,如果您使用的是 PHP 5.5 或更高版本,您可能应该尝试使用 curl_file_create() 而不是添加 @/full/file/path 作为文件字段值。

    在 PHP 5.5 或更新版本中使用旧方法

    如果您使用的是 PHP 5.5 或更新版本,则在使用旧的上传文件方式时可能会遇到问题。

    首先是您必须使用CURLOPT_SAFE_UPLOAD 选项并将其设置为FALSE

    其次,让我花费数小时调试的事情是,您必须在设置 CULROPT_POSTFIELDS 之前执行此操作。如果您使用curl_setopt_array(),则应将CURLOPT_SAFE_UPLOAD 添加到该数组中CURLOPT_POSTFIELDS 之前。如果您使用的是curl_setopt(),那么您只需在之前设置CURLOPT_SAFE_UPLOAD。否则将导致文件字段作为包含@/full/file/path 字符串的文本发送,而不是正确上传文件。

    使用旧方法的示例,但即使使用较新的版本也应该可以工作

    <?php
    $options = array(
      CURLOPT_URL => $url,
      CURLOPT_RETURNTRANSFER => TRUE,
      CURLOPT_SAFE_UPLOAD => FALSE,
      CURLOPT_POSTFIELDS => array(
        'text1' => 'test',
        'submit' => 'Send!',
        'file1' => '@' . realpath('images/a.jpg'),
        'file2' => '@' . realpath('images/b.jpg'),
      ),
    );
    $ch = curl_init();
    // Needed for PHP > 5.5 to enable the old method of uploading file.
    // Make sure to include this before CURLOPT_POSTFIELDS.
    if (defined('CURLOPT_SAFE_UPLOAD')) {
      curl_setopt($ch, CURLOPT_SAFE_UPLOAD, FALSE);
    }
    curl_setopt_array($ch, $options);
    $content = curl_exec($ch);
    $info = curl_getinfo($ch);
    curl_close($ch);
    

    full code here

    PHP 5.5 或更新版本应该这样使用

    $options = array(
      CURLOPT_URL => $url,
      CURLOPT_RETURNTRANSFER => TRUE,
      CURLOPT_POSTFIELDS => array(
        'text1' => 'test',
        'submit' => 'Send!',
        'file1' => curl_file_create(realpath('images/a.jpg')),
        'file2' => curl_file_create(realpath('images/b.jpg')),
      ),
    );
    
    $ch = curl_init();
    curl_setopt_array($ch, $options);
    $content = curl_exec($ch);
    $info = curl_getinfo($ch);
    curl_close($ch);
    

    full code here

    【讨论】:

    • 非常感谢你救了我的命
    • 我很高兴它有帮助。感谢您抽出宝贵时间回信!
    【解决方案2】:

    好的,我已经找到了问题所在,希望该解决方案能帮助很多不想改变他们的代码来代替其他人的人。

    cURL 没有检测到它应该将此表单作为多部分发送,因此它将帖子作为默认编码发送,这意味着另一端没有接收到 $_FILES 变量。

    要解决此问题,您需要将 postdata 作为数组提供,我正在为发送创建字符串,我已将其删除并为 CURLOPT_POSTFIELDS 提供了一个数组。

    使用 cURL 直接从表单上传时,另一件重要的事情是将文件信息与实际文件一起包含。

    我的 API 调用处理程序现在按如下方式创建了数组:

    public function uploadStreamPhoto($file)
    {
    
        $result = $this->request(API_URL_ADD_PHOTO, array(
        'accessToken' => $this->accessToken,
        'file' => "@$file;filename=".time().".jpg",
        'photoName' => time(),
        'albumName' => 'Stream'
        )); 
    
        return $result;
    
    }
    

    请注意 $file 变量是 $_FILES['tmp_name'] 然后您还必须定义文件名。我将使用解决方案更新问题。

    【讨论】:

      【解决方案3】:
      function curl_grab_page($url,$data,$secure="false",$ref_url="",$login = "false",$proxy = "null",$proxystatus = "false")
      
                  {
                      if($login == 'true') {
                          $fp = fopen("cookie.txt", "w");
                          fclose($fp);
                      }
                      $ch = curl_init();
                      curl_setopt($ch, CURLOPT_COOKIEJAR, "cookie.txt");
                      curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt");
      
                      curl_setopt($ch, CURLOPT_TIMEOUT, 60);
                      curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
                      if ($proxystatus == 'true') {
                          curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, TRUE);
                          curl_setopt($ch, CURLOPT_PROXY, $proxy);
                      }
                      curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
      
                      if($secure=='true')
                      {
                          curl_setopt($ch, CURLOPT_SSLVERSION,3);
                      }
      
                      curl_setopt( $ch, CURLOPT_HTTPHEADER, array( 'Expect:' ) );
      
      
                      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
      
                      curl_setopt($ch, CURLOPT_URL, $url);
                      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                      curl_setopt($ch, CURLOPT_REFERER, $ref_url);
                      curl_setopt($ch, CURLOPT_HEADER, TRUE);
                      curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
                      curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
                      curl_setopt($ch, CURLOPT_POST, TRUE);
                      curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
                      ob_start();
      
                      return curl_exec ($ch); // execute the curl command
      
                      curl_getinfo($ch);
                      ob_end_clean();
                      curl_close ($ch);
                      unset($ch);
                  }
      

      根据您的需要使用此 curl 功能,因为我使用它在 post even 文件中发送数据。

      $data['FileName'] = '@'.$ProperPath;
      

      // 正确路径 = c:/images/a.jpg

      curl_grab_page("url", $data);
      

      【讨论】:

      • 复制和粘贴代码不多,您能看看我发布的内容并尝试帮助确定问题,我需要在我的代码中解决问题。
      • 您没有正确使用 curl,这就是为什么我向您发送了适用于所有事情的正确 curl 代码。 $this-&gt;extractRequestPostFields($postFields) 你在 curl 中不需要这个,因为如果它是一个数组,它会自动以你想要发送它的格式发送数据 application/x-url-encoded 和 encrypt/multipart 并且你必须在文件所在的位置添加一个正确的路径存储不是临时路径
      • cURL 使用正确,它是文件应该发送到的部分,而不是围绕文档挖掘我想我知道现在的问题是什么。
      • 您可以很好地使用您的代码,但不要使用 $_File[]['tmp'] 将其存储在某处,然后将路径粘贴到您的 $file = c:/uploadedfile/filename;
      • 嗯,我明白你的意思了,好的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-18
      • 2013-09-24
      • 2011-01-07
      • 1970-01-01
      • 2011-06-12
      • 1970-01-01
      相关资源
      最近更新 更多