cURL not sending file to API CALL

不羁的心 提交于 2021-01-07 05:39:45

问题


I am building a mobile site that runs from an API and have an API CALL handler class which does all the calls which I run from a primary functions file.

The issue here is my files are not being sent through to the API and it's not recognising what is a file and is returning a file not present error.

NOTE: ISSUE SOLVED AND WORKING CODE BELOW

Code Below:

FORM

<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>

UPLOAD FUNCTION

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');

    }

}

HANDLER METHOD

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 REQUEST METHOD

/**
* 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;

}

回答1:


My 2 cents for those ending up here by after the release of PHP 5.5. There are two things worth mentioning:

PHP 5.5 change

In PHP 5.5 a new function was introduced that changed the file upload procedure. rfc:curl-file-uploads describes it the best. So if you are using PHP 5.5 or newer, you should probably try to use curl_file_create() instead of adding @/full/file/path as the file field value.

Using legacy method in PHP 5.5 or newer

If you are using PHP 5.5 or newer, you might encounter issues when using old way of uploading files.

First of them is the fact that you have to use CURLOPT_SAFE_UPLOAD option and set it to FALSE.

Second, and the thing that made me spend hours debugging, is that you have to do this before setting CULROPT_POSTFIELDS. If you use curl_setopt_array() then CURLOPT_SAFE_UPLOAD should be added to that array before CURLOPT_POSTFIELDS. If you are using curl_setopt() then you just have to set CURLOPT_SAFE_UPLOAD before. Failing to do this will cause the file fields to be send as text containing @/full/file/path string instead of properly uploading files.

Example using legacy method but should work even with newer versions

<?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 or newer should be used like this

$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:


OK I have found out what the issue was, hopefully the solution will help a lot of people who don't want to change how their code is in lieu of someone elses.

cURL was not detecting that it was supposed to send this form as a multipart so it was sending the post as a default encoding meaning the other end wasn't receiving the $_FILES variable.

To solve this you need to give the postdata as an array, I was creating the string for the send, I have removed this and am giving the CURLOPT_POSTFIELDS an array.

Another important thing when uploading directly from a form using cURL is to include the information for your file along with the actual file.

My API Call handler now created the array as follows:

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;

}

Take note that the $file variable is $_FILES['tmp_name'] You then also have to define the file name. I will be updating the question with the solution.




回答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);
            }

use this curl function according to your need as i was using it to send data in post even files.

and

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

// Proper Path = c:/images/a.jpg

curl_grab_page("url", $data);


来源:https://stackoverflow.com/questions/14646653/curl-not-sending-file-to-api-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!