Multipart form file upload POST PHP cURL

前端 未结 4 556
慢半拍i
慢半拍i 2021-01-15 02:30

I am wanting to send a file via http POST using PHP and cURL.

The form POST was working ok with basic fields besides the file being posted with \'application/json\'.

相关标签:
4条回答
  • 2021-01-15 02:56

    One omission I see is that you need to add your $cfile object to the $data array. This, coupled with the answer by Samir, should get you all squared away.

    0 讨论(0)
  • 2021-01-15 02:58

    This all gets very confusing and "contradictory" very quickly! Because cUrl is quite flexible and powerful, little differences in usage context have a massive impact and can lead to DAYS of non-existent bug chasing.

    Secondly, the URL/Endpoint you are posting to can also have it own "implementation" and expectations. This understanding it complicated when experience is only with GET requests AND the assumption/expectation is based of PHP Super Easy $_REQUEST

    In the case above, simplifying: This is a live working example, but the postfields ($post) has been reduced from the 50 odd in use to a few for example. This will post as multipart form data.

    Here important options are the options to use CURLOPT_POST and CURLOPT_POSTFIELDS and NOT CURLOPT_CUSTOMREQUEST. Doing so will require you to take care of required headers and in particular, content size header, etc.

    // Post "field" array. Notice its 1 Dimensional. Else, this should rather accept JSON. simply decode array to json and proceed). Depends what server is expecting - Form data, Form + files, json or maybe just a RAW request body.
    $post = array(  
                'RsmMaster1_TSM' => $tsm,
                '__EVENTTARGET' => '__Page',
                '__EVENTARGUMENT' => 'ExcelExport',
                '__VIEWSTATE'  => $viewstate,
                '__VIEWSTATEGENERATOR'  => $viewstategenerator,
                '__EVENTVALIDATION'  => $eventvalidation
     );
    
    // Optional, Required in THIS case because, well gosh darn who knows, as the receiving server admin?
    $headers = array(   
                    'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
                    'Accept-Language: en-ZA,en-GB;q=0.8,en-US;q=0.5,en;q=0.3',
                    'Referer: https://example.com/Main.aspx'  
                );
    
    // cUrl it into the goal!
    $ch = curl_init();
    
    curl_setopt($ch, CURLOPT_URL, 'https://example.com/Main.aspx');
    curl_setopt($ch, CURLOPT_POST, TRUE);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post);                                                                  
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
    curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7.12) Gecko/20050915 Firefox/1.0.7");
    curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate');                                                                   
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);    
    curl_setopt($ch, CURLOPT_HEADER, 0);
    // curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie); // Session maintain!
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_FAILONERROR,    TRUE   );
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE  );
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE  );
    
    $content = curl_exec($ch);
    curl_close($ch);
    
    0 讨论(0)
  • 2021-01-15 03:07

    You need to build query string for data to be posted. Use http_build_query

    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
    
    0 讨论(0)
  • 2021-01-15 03:14

    Hi I have figured out the problem.

    My params were not set correct on the api endpoint. Need to set a note_id(c_id)

    But issue I am having now is posting all data at once. I am posting file after the note has been created thus generating the note id for me for posting file. Can anyone help with that? I can post a new question.

    See updated code below:

    //$orgID = (is_numeric($_POST['orgID']) ? (int)$_POST['orgID'] : 0);
    //$noteTitle = (isset($_POST['noteTitle']) ? $_POST['noteTitle'] : null);
    //$noteBody = (isset($_POST['noteBody']) ? $_POST['noteBody'] : null);
    
    $noteID = (isset($_POST['noteID']) ? $_POST['noteID'] : null);
    
    $localFile = $_FILES['file']['tmp_name'];
    $fp = fopen($localFile, 'r');
    
    $curl = curl_init();
    
    $cfile = new CURLFILE($_FILES['file']['tmp_name'], $_FILES['file']['type'], $_FILES['file']['name']);
    $data = array();                
    //$data["TITLE"] = "$noteTitle";
    //$data["BODY"] = "$noteBody";
    //$data["LINK_SUBJECT_ID"] = "$orgID";
    //$data["LINK_SUBJECT_TYPE"] = "Organisation";        
    $data['FILE_ATTACHMENTS'] = $cfile;
    
    curl_setopt_array($curl, array(
      CURLOPT_UPLOAD => 1,
      CURLOPT_INFILE => $fp,
      CURLOPT_NOPROGRESS => false, 
      CURLOPT_BUFFERSIZE => 128,
      CURLOPT_INFILESIZE => filesize($localFile),
      CURLOPT_URL => "https://api.insight.ly/v2.1/Notes/?c_id=" . $noteID . "&filename=" . $_FILES['file']['name'],
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_ENCODING => "",
      CURLOPT_MAXREDIRS => 10,
      CURLOPT_TIMEOUT => 30,
      CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
      CURLOPT_CUSTOMREQUEST => "POST",
      CURLOPT_POSTFIELDS => $data,      
      CURLOPT_HTTPHEADER => array(
        "authorization: Basic xxx",
        "cache-control: no-cache",
        "content-type: multipart/form-data",
        "postman-token: xxx"
      ),
    ));
    $response = curl_exec($curl);
    $err = curl_error($curl);
    
    curl_close($curl);
    
    if ($err) {
      echo "cURL Error #:" . $err;
    } else {
      echo $response;
    }
    

    HTML

    <form method="POST" action="formSend.php" enctype="multipart/form-data">
        //<input type="text" value="" name="orgID">
        //<input type="text" value="" name="noteTitle">
        //<input type="text" value="" name="noteBody"> 
        <input type="text" value="" name="noteID">
        <input name="file" type="file" id="file"/>
        <input type="submit" value="Submit" name="btnUpload"/>
    </form>
    

    If anyone is interested this is my solution for using fpdf to generate a PDF document from the web form then auto send, instead of the file upload. FPDF file ---> send via CURL automatically NOT with file upload

    0 讨论(0)
提交回复
热议问题