如何通过curl发布将文件上传到api

时间:2018-09-24 10:55:02

标签: php codeigniter curl codeigniter-2 php-curl

这是$ _POST

Array
(
 [name] => image.png
 [type] => image/png 
 [tmp_name] => C:\xampp5\tmp\phpA637.tmp
 [error] => 0
 [size] => 16412
)

这是代码:

$curl = curl_init();

        curl_setopt_array($curl, array(
            CURLOPT_PORT => "2403",
            CURLOPT_URL => "http://".cfg('api_ip').":2403/sk_group/update_profile_pic", //url
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => "",
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => "POST",
            CURLOPT_POSTFIELDS => "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"data\"\r\n\r\n{\"groupId\":\"".$group."\",\"profile_pic\":\"".$name."\"}\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"profile_pic\"; filename=\"".$file."\"\r\nContent-Type: ".$type."\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--",
            CURLOPT_HTTPHEADER => array(            
                "SessionId: ".$_SESSION['session']."",
                "VersionCode: ".cfg('version_code')."",
                "content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"
            ),
        ));

        $response = curl_exec($curl);
        $err = curl_error($curl);

        curl_close($curl);

        if ($err) {
            echo "cURL Error #:" . $err;
        } else {
            redirect("/meme/me/group"."?msg=".urldecode('Update icon group succes')."&type_msg=success");
    }

我想知道如何将$ file文件成功上传到图像,导致$ _POST仅显示文件名而不显示全路径。


更新


这是我拥有的控制器中的全部功能

function one()
    {   
        $filename = $_FILES['icon']['name'];    
        $filedata = $_FILES['icon']['tmp_name'];
        $filetype = $_FILES['icon']['type'];

        two($_POST['group'], $filename, $filedata, $filetype);
    }

我的助手上的此功能

function two($group, $name, $file, $type)
{   
    $cFile = new CURLFile($file,$type,$name);

    $curl = curl_init();

    curl_setopt_array($curl, array(
        CURLOPT_PORT => "2403",
        CURLOPT_URL => "http://".cfg('api_ip').":2403/sk_group/update_profile_pic",
        CURLOPT_HEADER => true,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_FOLLOWLOCATION => true,     
        CURLOPT_ENCODING => "",
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => "POST",
        CURLOPT_POSTFIELDS => "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"data\"\r\n\r\n{\"groupId\":\"".$group."\",\"profile_pic\":\"".$name."\"}\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"profile_pic\"; filename=\"".$cFile."\"\r\nContent-Type: ".$type."\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--",
        CURLOPT_HTTPHEADER => array(            
            "SessionId: ".$_SESSION['session']."",
            "VersionCode: ".cfg('version_code')."",
            "content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"
        ),
    ));

    $response = curl_exec($curl);
    $err = curl_error($curl);

    curl_close($curl);

    if ($err) {
        echo "cURL Error #:" . $err;
    } else {
        redirect("/meme/me/group"."?msg=".urldecode('Update icon group succes')."&type_msg=success");
    }
}
  

仍然有与我询问...相同的问题,文件在哪里?以及如何将其发布到成功?

1 个答案:

答案 0 :(得分:0)

我已经发布了相同的答案here

从PHP 5.5及更高版本开始,CURL将使用CURL File上载文件,对于较低的PHP版本,您需要手动生成表单边界,然后发送文件。以下代码示例可处理这两种情况。

为简便起见,这是主要部分:

<?php

$file = "websites.txt";
upload_with_compatibility($file);

function upload_with_compatibility($file){
    if (version_compare(phpversion(), '5.5', '>=')) {
        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);
}
?>