2024 年日本 PHP 研討會

CURLFile 類別

(PHP 5 >= 5.5.0, PHP 7, PHP 8)

簡介

這個類別或 CURLStringFile 應該用於使用 CURLOPT_POSTFIELDS 上傳檔案。

不允許反序列化 CURLFile 實例。從 PHP 7.4.0 開始,序列化本身就被禁止。

類別概要

類別 CURLFile {
/* 屬性 */
公開 字串 $name = "";
公開 字串 $mime = "";
公開 字串 $postname = "";
/* 方法 */
公開 __construct(字串 $filename, ?字串 $mime_type = null, ?字串 $posted_filename = null)
公開 setMimeType(字串 $mime_type): void
公開 setPostFilename(字串 $posted_filename): void
}

屬性

name(名稱)

要上傳的檔案名稱。

mime(MIME 類型)

檔案的 MIME 類型(預設為 application/octet-stream)。

postname(POST 檔案名稱)

上傳資料中檔案的名稱(預設為 name 屬性)。

目錄

新增註解

使用者貢獻的註解 5 則註解

alin dot rzv at gmail dot com
10 年前
我看到了一些負評,這裡是一個使用 curl 上傳圖片的小範例。

<?php
$target
="http://youraddress.tld/example/upload.php";

# https://php.dev.org.tw/manual/en/curlfile.construct.php

// 建立一個 CURLFile 物件 / 程序式方法
$cfile = curl_file_create('resource/test.png','image/png','testpic'); // 嘗試新增

// 建立一個 CURLFile 物件 / 物件導向方法
#$cfile = new CURLFile('resource/test.png','image/png','testpic'); // 取消註釋並使用,如果上述程序式方法無效。

// 指定 POST 資料
$imgdata = array('myimage' => $cfile);

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $target);
curl_setopt($curl, CURLOPT_USERAGENT,'Opera/9.80 (Windows NT 6.2; Win64; x64) Presto/2.12.388 Version/12.15');
curl_setopt($curl, CURLOPT_HTTPHEADER,array('User-Agent: Opera/9.80 (Windows NT 6.2; Win64; x64) Presto/2.12.388 Version/12.15','Referer: http://someaddress.tld','Content-Type: multipart/form-data'));
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 停止驗證憑證
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true); // 啟用 POST
curl_setopt($curl, CURLOPT_POSTFIELDS, $imgdata); // POST 圖片
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); // 如果上傳後有任何重新導向
$r = curl_exec($curl);
curl_close($curl);

?>
CertaiN
10 年前
在 multipart POST 請求中存在「@」的問題。

PHP 5.5 或更高版本的解決方案
- 啟用 CURLOPT_SAFE_UPLOAD。
- 使用 CURLFile 取代「@」。

PHP 5.4 或更早版本的解決方案
- 自行建構 multipart 內容主體。
- 自行更改「Content-Type」標頭。

以下程式碼片段將幫助您 :D

<?php

/**
* For safe multipart POST request for PHP5.3 ~ PHP 5.4.
*
* @param resource $ch cURL resource
* @param array $assoc "name => value"
* @param array $files "name => path"
* @return bool
*/
function curl_custom_postfields($ch, array $assoc = array(), array $files = array()) {

// invalid characters for "name" and "filename"
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
return @curl_setopt_array($ch, array(
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => implode("\r\n", $body),
CURLOPT_HTTPHEADER => array(
"Expect: 100-continue",
"Content-Type: multipart/form-data; boundary={$boundary}", // change Content-Type
),
));
}

?>
php at miknik dot co dot uk
6 年前
用於從檔案路徑建構 CURLFile 的簡單函式

function makeCurlFile($file){
$mime = mime_content_type($file);
$info = pathinfo($file);
$name = $info['basename'];
$output = new CURLFile($file, $mime, $name);
return $output; // 返回 $output;
}

Then construct an array of all the form fields you want to post. For each file upload just add the CURLFiles. // 接著,建構一個包含所有您想發布的表單欄位的陣列。對於每個檔案上傳,只需加入 CURLFiles。

$ch = curl_init("https://api.example.com"); // $ch = curl_init("https://api.example.com");
$mp3 =makeCurlFile($audio); // $mp3 = makeCurlFile($audio);
$photo = makeCurlFile($picture); // $photo = makeCurlFile($picture);
$data = array('mp3' => $mp3, 'picture' => $photo, 'name' => 'My latest single', 'description' => 'Check out my newest song'); // $data = array('mp3' => $mp3, 'picture' => $photo, 'name' => '我的最新單曲', 'description' => '來聽聽我的新歌');
curl_setopt($ch, CURLOPT_POST,1); // curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$result = curl_exec($ch); // $result = curl_exec($ch);
if (curl_errno($ch)) { // if (curl_errno($ch)) {
$result = curl_error($ch); // $result = curl_error($ch);
}
curl_close ($ch); // curl_close($ch);
php at richardneill dot org // php at richardneill dot org
4 months ago // 4 個月前
CURLFile() is great with Content-Type: "multipart/form-data". // CURLFile() 非常適合處理 Content-Type: "multipart/form-data"。

But, if you want to upload just a single file (e.g. for the Wordpress media API), then you have to do this WITHOUT using CURLFile(). i.e. // 但是,如果您只想上傳單個檔案(例如,使用 WordPress 媒體 API),那麼您必須在「不使用」CURLFile() 的情況下執行此操作。也就是說:

1. Set the relevant CURLOPT_HTTPHEADER values // 1. 設定相關的 CURLOPT_HTTPHEADER 值
"Content-Type: image/jpeg" // "Content-Type: image/jpeg"
"Content-Disposition: attachment; filename=myfile.jpg" // "Content-Disposition: attachment; filename=myfile.jpg"
(where the content-type needs to be the appropriate mime-type for the uploaded file, and filename is the basename of the file). // (其中 content-type 必須是上傳檔案的適當 MIME 類型,而 filename 是檔案的基本名稱)。

2. Post the file contents directly within CURLOPT_POSTFIELDS // 2. 直接在 CURLOPT_POSTFIELDS 中發布檔案內容
file_get_contents($filename); // file_get_contents($filename);
ohcc at 163 dot com // ohcc at 163 dot com
7 years ago // 7 年前
This is how to upload two or more files at once with cURLFile. // 以下是使用 cURLFile 一次上傳兩個或多個檔案的方法。

With modern browser support, you can upload many files at one time if the multiple attribute is given. // 透過現代瀏覽器的支援,如果提供了 multiple 屬性,您可以一次上傳多個檔案。

<input type="file" name="file[]" muliple /> // <input type="file" name="file[]" multiple />

With outdated browser you can place many input elements to do that. // 對於過時的瀏覽器,您可以放置多個 input 元素來執行此操作。

<input type="file" name="file[]" /> // <input type="file" name="file[]" />
<input type="file" name="file[]" /> // <input type="file" name="file[]" />
<input type="file" name="file[]" /> // <input type="file" name="file[]" />

Here's the php code to handle multiple uploads. // 以下是處理多個上傳的 PHP 程式碼。

... // (程式碼翻譯維持英文,因程式碼中英文專有名詞較多,翻譯可能造成誤解)

Don't leave the square brackets in ''file[0]'' empty like 'file[]', in that way only the last file will be received by the remote server. // 不要將 'file[0]' 中的方括號留空,例如 'file[]',這樣遠端伺服器只會收到最後一個檔案。
To Top