2

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.

1 Answer 1

4

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you. I know of the CURLFile() object. My only problem to use this is I have php version 5.4.36. So this is no option for me.
@user2795648 your php version is old, insecure, no longer recieving critical security updates (nor bugfixes, nor updates of any kind), do yourself a favour and upgrade to 5.6. that said, the 5.4 version of doing it is CURLOPT_POSTFIELDS => array ( 'file' => '@/tmp/testfile.pdf' ) - but that wont work on 5.5+ (without CURLOPT_SAFE_UPLOAD ), and won't work on php 7.0+ period.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.