简体   繁体   中英

php curl multipart/form-data : file content not posted

Many answers yet on this topic on this website, but none helps me.

I am trying to post a file to box (cloud storage). Should be easy but it is not.

I use RequestBin to debug.

When using curl on commandline, it works great (file is posted to Box) :

curl https://requestb.in/1bw1 -H "Authorization: Bearer supersecret" -H "Content-Type: multipart/form-data" -X POST -F file=@/tmp/testfile.pdf

When trying to do the same (upload a file to Box) with php curl it fails (with no response at all, which means no file content could be found).

I also see on RequestBin that my POST looks different.

Curl cli (correct) :

RAW BODY

------------------------------cd86e864290b Content-Disposition: form-data; name="attributes"

{"name":"testfile.pdf", "parent":{"id":"40801665641"}} ------------------------------cd86e864290b Content-Disposition: form-data; name="file"; filename="testfile.pdf" Content-Type: application/octet-stream

RIFFäÊWAVEfmt ...

Curl php (not correct) :

RAW BODY

------------------------------7ab3fffab8c6 Content-Disposition: form-data; name="attributes"

{"name":"testfile.pdf","parent":{"id":"42035106321"}} ------------------------------7ab3fffab8c6 Content-Disposition: form-data; name="file"

@../faxout/testfile.pdf ------------------------------7ab3fffab8c6--

This is cleary not the same and I don't know how to get the same result.

My PHP code :

$dataFile = array(
        'name' => $faxfilename,
        'parent' => array(
                'id' => $subfolderID,
            )
        );
    $PostData= array(
        'attributes' => json_encode($dataFile),
        'file' => "@$target"
    );
    $headers3=array(
        "Authorization: Bearer supersecret",
        "Content-Type: multipart/form-data"
        );

    //$filesurl = "https://upload.box.com/api/2.0/files/content";
    $filesurl = 'https://requestb.in/1bw1';
    $curlFILE = curl_init();
    curl_setopt_array($curlFILE, array(
        CURLOPT_URL => $filesurl,
        CURLOPT_HTTPHEADER => $headers3,
        CURLOPT_POST => TRUE,
        CURLOPT_POSTFIELDS => $PostData,
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_SSL_VERIFYPEER => FALSE,
        CURLOPT_SSL_VERIFYHOST => FALSE
    ));

I have tried :

CURLOPT_POSTFIELDS => http_build_query($PostData),

I have tried :

'@'.realpath($target)

I just don't seem to get the correct format for the file I want to post.

you're looking for CURLFile .

$curlFILE = curl_init ();
curl_setopt_array ( $curlFILE, array (
        CURLOPT_URL => 'https://requestb.in/1bw1',
        CURLOPT_HTTPHEADER => array (
                "Authorization: Bearer supersecret" 
        ),
        CURLOPT_POST => TRUE,
        CURLOPT_POSTFIELDS => array (
                'file' => new CURLFile ( '/tmp/testfile.pdf' ) 
        ),
        //CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_SSL_VERIFYPEER => FALSE,
        CURLOPT_SSL_VERIFYHOST => FALSE 
) );
curl_exec($curlFILE);

also, when using multipart/form-data or application/x-www-urlencoded encoding, don't set the content-type header manually, curl will set the appropriate header for you automatically, and unlike you, curl won't make any typos in doing so.

also, curl_setopt_array returns bool(false) if there was a problem setting your options, and you should not ignore those errors, thus i recommend using this function instead, it converts any curl setopt errors to a RuntimeException

function ecurl_setopt_array($ch, array $options) {
    if (! curl_setopt_array ( $ch, $options )) {
        throw new \RuntimeException ( 'curl_setopt_array failed. ' . curl_errno ( $ch ) . ': ' . curl_error ( $ch ) );
    }
}

and a protip, when debugging curl code, enable CURLOPT_VERBOSE.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM