curl_file_create
函数的第一个参数是文件名。有没有办法直接使用文件的内容?
我不想在临时文件中写入内容并在函数中使用该文件名。
更多扩展:
我用$image = file_get_contents('http://example.com/image.jpg');
函数从 URL 获取图像,所以我有一个$image
变量与二进制图像内容现在,在得到它之后,我需要将此图像作为表单的一部分发布到另一个 URL,而无需使用磁盘上的临时文件。
这是可能的,当然,但你几乎肯定要使用 tmpfile()技巧,例如,如果你有一个名为$file_content
的变量,你想上传一个文件,但你没有一个文件,做
<?php
$file_content = "the content of the *file* i want to upload, which does not exist on disk";
$file_name = "example.bin";
$tmph = tmpfile(); // will create a file in the appropriate temp folder when an unique filename
fwrite($tmph, $file_content);
$tmpf = stream_get_meta_data($tmph)['uri'];
$ch = curl_init('http://target_url/');
curl_setopt_array($ch, array(
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => array(
'file' => new CURLFile($tmpf, 'application/octet-stream', $file_name)
)
));
curl_exec($ch);
fclose($tmph); // thanks to tmpfile() magic, the file is automatically deleted when fclosed()'d
unset($tmph, $tmpf); // unset() is not needed, but this is the end of the tmpfile()-trick.
..只要上传很快,我们不调用 fflush($tmph);,文件可能永远不会接触实际的磁盘,它只是在 IO 缓存中创建,计划稍后写入磁盘,然后删除(从 io 缓存)-这个代码也受到 PHP 的垃圾收集器的保护,如果代码中有一个未捕获的异常 / 错误停止执行,PHP 的垃圾收集器文件将删除
然而,这里是如何实际上传的Multipart/form-data
格式的文件,而无需也不创建一个磁盘上的文件,通过创建Multipart/form-data
-请求与 userland PHP 代码:
用法示例:
<?php
// normal php-way:
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL=>'https://example.com/',
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => array(
'sample_variable' => 'anything',
'file' => new CURLFile("path/to/file.txt")
)
));
curl_exec($ch);
curl_close($ch);
// ty_multipart-way:
$post_data = array();
$tmp = new ty_multipart_variable();
$tmp->post_name = 'sample_variable';
$tmp->content = 'anything';
$post_data[] = $tmp;
$tmp = new ty_multipart_file();
$tmp->post_name = 'file';
$tmp->post_file_name = "file.ext";
$tmp->content = 'contents of file.ext';
$post_data[] = $tmp;
$content_type_header="";
$post_body=ty_multipart_form_data_generator($post_data,$content_type_header);
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL=>'https://example.com/',
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $post_body,
CURLOPT_HTTPHEADER=>array(
$content_type_header
)
));
curl_exec($ch);
curl_close($ch);
实现:
cl ty_multipart_file
{
public $post_name = "";
public $file_name = "";
public $content_type = "application/octet-stream";
public $content = "";
public $additional_headers = [];
}
cl ty_multipart_variable
{
public $post_name = "";
public $content = "";
public $additional_headers = [];
}
function ty_multipart_form_data_generator(array $postfields, string &$out_content_type_header): string
{
// Content-Type: multipart/form-data; boundary=------------------------7b5b9abe8c56fd67
// same boundary format as used by curl
$boundary = "------------------------" . strtolower(bin2hex(random_bytes(8)));
$out_content_type_header = 'Content-Type: multipart/form-data; boundary=' . $boundary;
$body = "";
foreach ($postfields as $unused => $post) {
$body .= $boundary . "\r\n";
if (is_a($post, 'ty_multipart_variable')) {
$body .= "Content-Disposition: form-data; name=\"{$post->post_name}\"\r\n";
foreach ($post->additional_headers as $header) {
$body .= $header . "\r\n";
}
$body .= "\r\n";
$body .= $post->content . "\r\n";
} elseif (is_a($post, 'ty_multipart_file')) {
$body .= "Content-Disposition: form-data; name=\"{$post->post_name}\"; filename=\"{$post->file_name}\"\r\n";
$body .= "Content-Type: " . $post->content_type . "\r\n";
foreach ($post->additional_headers as $header) {
$body .= $header . "\r\n";
}
$body .= "\r\n";
$body .= $post->content . "\r\n";
} else {
throw new \InvalidArgumentException("postfields key {$unused} is not an instance of ty_multipart_variable NOR an instance of ty_multipart_file!");
}
}
$body .= $boundary . "--\r\n";
return $body;
}
本站系公益性非盈利分享网址,本文来自用户投稿,不代表边看边学立场,如若转载,请注明出处
评论列表(18条)