CURL call not uploading the file from local to remote server PHP

后端 未结 1 1401
Happy的楠姐
Happy的楠姐 2021-01-29 03:48

Hi I am having the following CURL call which will upload the local text file to another location, as of now in localhost only (ie. for testing purpose, once it runs successfully

1条回答
  •  猫巷女王i
    2021-01-29 04:28

    Try the following code, I have updated it according to your need. Also when we post a file it will not be displayed using $_POST as you are doing, instead to see files you need to print $_FILES

    I have not tested your code, but to me, it seems fine. Your major mistake is that you are printing the upload file using $_POST. File uploads are available in $_FILES array. Try to print that.

    Upload file: (This is compatible even with older versions of PHP) Please note that, for compatibity purpose, when CURLFile is not available (for PHP less than 5.5) I have used file_get_contents.

    =')) {
            echo "Upload will be done using CURLFile\n";
            upload($file); //CURL file upload using CURLFile for PHP v5.5 or greater
        }else{
            echo "Upload will be done without CURLFile\n";
            compatibleUpload($file); //CURL file upload without CURLFile for PHP less than v5.5
        }
    }
    
    //Upload file using CURLFile
    function upload($file){
        $target = "http://localhost:8888/upload_file.php";
        $host = parse_url($target);
    
        $cFile = new CURLFile($file,'text/plain', $file);
        $data = array(
            'log_file' => $cFile,
        );
    
        //you can play around with headers, and adjust as per your need
        $agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36';
        $curlHeaders = array(
            'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
            'Accept-Encoding: gzip, deflate',
            'Accept-Language: en-US,en;q=0.8',
            'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36', //change user agent if you want
            'Connection: Keep-Alive',
            'Pragma: no-cache',
            'Referer: http://localhost:8888/upload.php', //you can change referer, if you want or remove it
            'Host: ' . $host['host'] . (isset($host['port']) ? ':' . $host['port'] : null), // building host header
            'Cache-Control: max-age=0',
            'Cookie: __utma=61117235.2020578233.1500534080.1500894744.1502696111.4; __utmz=61117235.1500534080.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)', //adjust your cookie if you want
            'Expect:  '
        );
    
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $target);
        curl_setopt($curl, CURLOPT_HEADER  , true); //we need header
        curl_setopt($curl, CURLOPT_USERAGENT,$agent);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $curlHeaders);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // stop verifying certificate
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 
        curl_setopt($curl, CURLOPT_POST, true); // enable posting
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data); // post images 
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); // if any redirection after upload
        curl_setopt($curl, CURLOPT_SAFE_UPLOAD, true);
        $r = curl_exec($curl);
        if (curl_errno($curl)) {
            $error = curl_error($curl);
            print_r($error);
        } else {
            // check the HTTP status code of the request
            $resultStatus = curl_getinfo($curl, CURLINFO_HTTP_CODE);
            if ($resultStatus != 200) {
                print_r($resultStatus);
            }else{
                //successfull
                print_r($r);
            }
        }
        curl_close($curl);
    }
    
    //Upload file without using CURLFile, because we are upload a file, so we need to generate form boundry
    function compatibleUpload($file){
        $target = "http://localhost:8888/upload_file.php";
        //use this to send any post parameters expect file types
        //if you are not sending any other post params expect file, just assign an empty array
        // $assoc = array(
        //     'name' => 'demo',
        //     'status' => '1'
        // );
        $assoc = array(); //like this
    
        //this array is used to send files
        $files = array('log_file' => $file);
    
        static $disallow = array("\0", "\"", "\r", "\n");
    
        // build normal parameters
        foreach ($assoc as $k => $v) {
            $k = str_replace($disallow, "_", $k);
            $body[] = implode("\r\n", array(
                "Content-Disposition: form-data; name=\"{$k}\"",
                "",
                filter_var($v), 
            ));
        }
    
        // build file parameters
        foreach ($files as $k => $v) {
            switch (true) {
                case false === $v = realpath(filter_var($v)):
                case !is_file($v):
                case !is_readable($v):
                    continue; // or return false, throw new InvalidArgumentException
            }
            $data = file_get_contents($v);
            $v = call_user_func("end", explode(DIRECTORY_SEPARATOR, $v));
            $k = str_replace($disallow, "_", $k);
            $v = str_replace($disallow, "_", $v);
            $body[] = implode("\r\n", array(
                "Content-Disposition: form-data; name=\"{$k}\"; filename=\"{$v}\"",
                "Content-Type: application/octet-stream",
                "",
                $data, 
            ));
        }
    
        // generate safe boundary 
        do {
            $boundary = "---------------------" . md5(mt_rand() . microtime());
        } while (preg_grep("/{$boundary}/", $body));
    
        // add boundary for each parameters
        array_walk($body, function (&$part) use ($boundary) {
            $part = "--{$boundary}\r\n{$part}";
        });
    
        // add final boundary
        $body[] = "--{$boundary}--";
        $body[] = "";
    
        // set options
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $target);
        curl_setopt($ch, CURLOPT_HEADER  , true); //we need header
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // stop verifying certificate
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt_array($ch, array(
            CURLOPT_POST       => true,
            CURLOPT_POSTFIELDS => implode("\r\n", $body),
            CURLOPT_HTTPHEADER => array(
                "Expect: ",
                "Content-Type: multipart/form-data; boundary={$boundary}", // change Content-Type
            ),
        ));
        $r = curl_exec($ch);
        if (curl_errno($ch)) {
            $error = curl_error($ch);
            print_r($error);
        } else {
            // check the HTTP status code of the request
            $resultStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            if ($resultStatus != 200) {
                print_r($resultStatus);
            }else{
                //successfully uploaded
                print_r($r);
            }
        }
        curl_close($ch);
    }
    ?>
    

    Upload handling:

    
    

    Sample I tried to upload: (websites.txt)

    Sat Sep 9 07:31:18 2017 notifications.google.com 192.168.150.201
    Sat Sep 9 07:31:18 2017 notifications.google.com 192.168.150.201
    Sat Sep 9 07:31:19 2017 plus.l.google.com 192.168.150.201
    Sat Sep 9 07:31:19 2017 plus.l.google.com 192.168.150.201
    

    Output of CURL result (PHP ver 5.5 and up)

    Upload will be done using CURLFile
    HTTP/1.1 200 OK
    Date: Wed, 13 Sep 2017 07:11:07 GMT
    Server: Apache
    X-Powered-By: PHP/5.5.38
    Keep-Alive: timeout=5, max=100
    Connection: Keep-Alive
    Transfer-Encoding: chunked
    Content-Type: text/html
    
    Array
    (
    )
    Array
    (
        [log_file] => Array
            (
                [name] => websites.txt
                [type] => text/plain
                [tmp_name] => /Applications/MAMP/tmp/php/phpRp8S4T
                [error] => 0
                [size] => 245
            )
    
    )
    

    Output of CURL result (PHP ver less than 5.5, I tested on 5.4.45)

    Upload will be done without CURLFile
    HTTP/1.1 200 OK
    Date: Wed, 13 Sep 2017 07:17:43 GMT
    Server: Apache
    X-Powered-By: PHP/5.4.45
    Transfer-Encoding: chunked
    Content-Type: text/html
    
    Array
    (
    )
    Array
    (
        [log_file] => Array
            (
                [name] => websites.txt
                [type] => application/octet-stream
                [tmp_name] => /Applications/MAMP/tmp/php/phpQWGlEG
                [error] => 0
                [size] => 245
            )
    
    )
    

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