通过cURL从PHP中的表单POST发送文件

Mar*_*ean 44 php curl image-uploading

我正在编写API,我想要处理表单上的文件上传POST.表单的标记不是太复杂:

<form action="" method="post" enctype="multipart/form-data">
  <fieldset>
    <input type="file" name="image" id="image" />
    <input type="submit" name="upload" value="Upload" />
  </fieldset>
</form>
Run Code Online (Sandbox Code Playgroud)

但是,我很难理解如何处理此服务器端并发送cURL请求.

我熟悉用POSTcURL 发送带有数据数组的请求,我读过的关于上传文件的资源告诉我在文件名前加上一个@符号.但是这些相同的资源具有硬编码的文件名,例如

$post = array(
    'image' => '@/path/to/myfile.jpg',
    ...
);
Run Code Online (Sandbox Code Playgroud)

这是哪个文件路径?我在哪里可以找到它?它会是什么样的$_FILES['image']['tmp_name'],在这种情况下我的$post数组应该是这样的:

$post = array(
    'image' => '@' . $_FILES['image']['tmp_name'],
    ...
);
Run Code Online (Sandbox Code Playgroud)

或者我是以错误的方式来做这件事的?任何建议都将非常感激.

编辑:如果有人可以给我一个代码片段,我将使用以下代码片段,那么我将非常感激.我主要是作为cURL参数发送的内容,以及如何将这些参数与接收脚本一起使用的示例(让我们curl_receiver.php为了参数而调用它).

我有这个网页表格:

<form action="script.php" method="post" enctype="multipart/form-data">
  <fieldset>
    <input type="file" name="image />
    <input type="submit" name="upload" value="Upload" />
  </fieldset>
</form>
Run Code Online (Sandbox Code Playgroud)

这将是script.php:

if (isset($_POST['upload'])) {
    // cURL call would go here
    // my tmp. file would be $_FILES['image']['tmp_name'], and
    // the filename would be $_FILES['image']['name']
}
Run Code Online (Sandbox Code Playgroud)

Jef*_*vis 59

这是一些将文件发送到ftp的生产代码(可能是一个很好的解决方案):

// This is the entire file that was uploaded to a temp location.
$localFile = $_FILES[$fileKey]['tmp_name']; 

$fp = fopen($localFile, 'r');

// Connecting to website.
$ch = curl_init();

curl_setopt($ch, CURLOPT_USERPWD, "email@email.org:password");
curl_setopt($ch, CURLOPT_URL, 'ftp://@ftp.website.net/audio/' . $strFileName);
curl_setopt($ch, CURLOPT_UPLOAD, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 86400); // 1 Day Timeout
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_NOPROGRESS, false);
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, 'CURL_callback');
curl_setopt($ch, CURLOPT_BUFFERSIZE, 128);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($localFile));
curl_exec ($ch);

if (curl_errno($ch)) {

    $msg = curl_error($ch);
}
else {

    $msg = 'File uploaded successfully.';
}

curl_close ($ch);

$return = array('msg' => $msg);

echo json_encode($return);
Run Code Online (Sandbox Code Playgroud)


Cha*_*esA 47

对于发现此帖并使用PHP5.5 +的人来说,这可能有所帮助.

我发现netcoder建议的方法不起作用.即这不起作用:

$tmpfile = $_FILES['image']['tmp_name'];
$filename = basename($_FILES['image']['name']);
$data = array(
    'uploaded_file' => '@'.$tmpfile.';filename='.$filename,
);
$ch = curl_init();   
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
Run Code Online (Sandbox Code Playgroud)

我会在$_POSTvar中收到'uploaded_file'字段 - 而$_FILESvar中没有任何内容.

事实证明,对于php5.5 +,curl_file_create()您需要使用一个新功能.所以上面会变成:

$data = array(
    'uploaded_file' => curl_file_create($tmpfile, $_FILES['image']['type'], $filename)
);
Run Code Online (Sandbox Code Playgroud)

由于@格式现已弃用.

  • 我在最近5小时内寻找这个命令!! NOBODY提到了curl_file_create()函数,非常感谢 (3认同)
  • curl_file_create() &lt;== 这个函数更救命。 (2认同)

net*_*der 26

这应该工作:

$tmpfile = $_FILES['image']['tmp_name'];
$filename = basename($_FILES['image']['name']);

$data = array(
    'uploaded_file' => '@'.$tmpfile.';filename='.$filename,
);

$ch = curl_init();   
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
// set your other cURL options here (url, etc.)

curl_exec($ch);
Run Code Online (Sandbox Code Playgroud)

在接收脚本中,您将拥有:

print_r($_FILES);
/* which would output something like
     Array (
        [uploaded_file] => Array (
            [tmp_name] => /tmp/f87453hf
            [name] => myimage.jpg
            [error] => 0
            [size] => 12345
            [type] => image/jpeg
        )
     )
*/
Run Code Online (Sandbox Code Playgroud)

然后,如果你想正确处理文件上传,你会做这样的事情:

if (move_uploaded_file($_FILES['uploaded_file'], '/path/to/destination/file.zip')) {
   // do stuff
}
Run Code Online (Sandbox Code Playgroud)

  • PHP $ _FILES数组将不会在PUT请求上填充,因为PHP期望通过POST上传$ _FILES.如果你想在PUT请求上接受文件上传,你必须手动为*multipart*格式解析*php:// input*流(这不是太难,但不能在评论中解释. ..). (3认同)

Joa*_*cer 10

对于我的@符号不起作用,所以我做了一些研究,发现这种方式,它对我有用,我希望这对你有所帮助.

    $target_url = "http://server:port/xxxxx.php";           
    $fname = 'file.txt';   
    $cfile = new CURLFile(realpath($fname));

        $post = array (
                  'file' => $cfile
                  );    

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $target_url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");   
    curl_setopt($ch, CURLOPT_HTTPHEADER,array('Content-Type: multipart/form-data'));
    curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);   
    curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);  
    curl_setopt($ch, CURLOPT_TIMEOUT, 100);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post);

    $result = curl_exec ($ch);

    if ($result === FALSE) {
        echo "Error sending" . $fname .  " " . curl_error($ch);
        curl_close ($ch);
    }else{
        curl_close ($ch);
        echo  "Result: " . $result;
    }   
Run Code Online (Sandbox Code Playgroud)