CURL调用未将文件从本地上传到远程服务器PHP [英] CURL call not uploading the file from local to remote server PHP

查看:73
本文介绍了CURL调用未将文件从本地上传到远程服务器PHP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下CURL调用,它将把本地文本文件上传到另一个位置,到目前为止,仅在本地主机中(即,出于测试目的,一旦成功运行,我将推送服务器位置)。但是问题是本地文本文件没有被发布。有什么方法可以发布文件。

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 I will push the server location). But the problem is the local text file is not getting posted. Is there any way to POST the file.

注意-我不想通过 file_get_contents FTP 上传。甚至我提到了其他问题,但都没有解决我的问题。

NOTE - I dont want to do this by file_get_contents or FTP upload. Even I referenced other question but didn't solve my problem.

<?php
/* CURL Initilization */
$curl = curl_init();
/* Setting the remove URL */
curl_setopt($curl, CURLOPT_URL, 'http://127.0.0.1/php_training/get_curl_call.php');
/* I want to return the transfer and store in data instead of outputing on screen */
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
/* To upload safely */
curl_setopt($curl, CURLOPT_SAFE_UPLOAD, true);
/* Enable sending the data as POST data */
curl_setopt($curl, CURLOPT_POST, true);
/* Sending the data using @ is before 5.5, now I am using curl_file_create */
/* realpath - will get the absolute path of the .txt file */
curl_setopt($curl, CURLOPT_POSTFIELDS, array(
      'log_file' => curl_file_create(realpath('websites.txt'))
    )
);
/* Store the response of curl execution */
$response = curl_exec($curl);
print_r($response, curl_error($curl));
curl_close($curl);

以下是 get_curl_call.php

<?php
// $filename = $_POST['log_file'];
print_r($_POST);exit;

以下是 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

get_curl_call.php

Array ( ) 

我无法纠正文件未上传的原因。

I am not able to rectify why the file is not getting uploaded. Any help really appreciated.

推荐答案

尝试以下代码,我已根据您的需要对其进行了更新。同样,当我们发布文件时,它不会像您一样使用 $ _ POST 显示,而是要查看文件,您需要打印 $ _ FILES

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

我尚未测试您的代码,但对我来说,这似乎还不错。您的主要错误是您正在使用 $ _ POST 打印上传文件。文件上传位于 $ _ 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.

上传文件:(即使旧版本的PHP都兼容)
请注意,出于兼容性目的,当CURLFile不是可用(对于低于5.5的PHP)我使用过file_get_contents。

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.

<?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);
}
?>

上传处理:

<?php
    print_r($_POST); //this will print post varibales expect file types
    print_r($_FILES); // this will print files that are posted
?>

我尝试上传的示例:(websites.txt)

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

CURL结果的输出(PHP版本5.5及更高版本)

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
        )

)

CURL结果的输出(PHP ver小于5.5,我在5.4.45上进行了测试)

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
        )

)

这篇关于CURL调用未将文件从本地上传到远程服务器PHP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆