robtimus / multipart
支持(流式)多部分的库
Requires
- php: >=5.4
Requires (Dev)
- phpunit/phpunit: ~4
This package is auto-updated.
Last update: 2024-09-23 16:17:19 UTC
README
支持(流式)多部分的库。
支持的multipart类型
multipart/form-data
要创建multipart/form-data对象,创建一个MultipartFormData
实例,添加表单字段,并调用finish()
。添加表单字段有两种方法
addValue($name, $value)
添加给定名称的字符串值。两个参数都是必需的。addFile($name, $filename, $content, $contentType, $contentLength = -1)
添加给定名称的文件。名称、文件名、内容和内容类型是必需的;内容长度是可选的,如果内容是字符串,则将被忽略。
示例
// the multipart object can take an optional pre-existing boundary
$multipart = new MultipartFormData();
$multipart->addValue('name', 'Rob');
$multipart->addFile('file', 'file.txt', 'Hello World', 'text/plain');
$multipart->finish();
具有相同参数名称的多个值或文件
MultipartFormData
遵循RFC 7578,而不是RFC 2388。这意味着具有相同参数名称的多个值或文件不是作为multipart/mixed字段发送,而是作为单独的部分发送。
PHP服务器要求多个值或文件使用以[]
结尾的名称发送。因为MultipartFormData
被编写来支持也其他不需要这种要求的服务器类型,所以添加这些值由调用者负责。例如
$multipart = new MultipartFormData();
$multipart->addValue('name', 'Rob');
$multipart->addFile('file[]', 'file.txt', 'Hello World', 'text/plain');
$multipart->addFile('file[]', 'file.html', '<html>Hello World</html>', 'text/html');
$multipart->finish();
multipart/related
要创建multipart/related对象,创建一个MultipartRelated
实例,添加根部分和任何内联文件,并调用finish()
。添加部分有两种方法
addPart($content, $contentType, $contentLength = -1, $contentTransferEncoding = '')
添加没有内容处理的部分。这应该用于根部分。内容类型和内容是必需的;内容长度是可选的,如果内容是字符串,则将被忽略;内容传输编码是可选的,如果设置了,则用于Content-Transfer-Encoding
头。addInlineFile($contentID, $filename, $content, $contentType, $contentLength = -1, $contentTransferEncoding = '')
添加内联文件。内容ID、文件名、内容类型和内容是必需的;内容长度是可选的,如果内容是字符串,则将被忽略;内容传输编码是可选的,如果设置了,则用于Content-Transfer-Encoding
头。
示例
// the multipart object can take an optional pre-existing boundary
$multipart = new MultipartRelated();
$multipart->addPart(file_get_contents('body.html'), 'text/html');
// the content length is irrelevant because the content is a string
$multipart->addInlineFile('logo', 'logo.png', base64_encode(file_get_contents('logo.png')), 'image/png', -1, 'base64');
$multipart->finish();
要在HTML正文中使用此内联文件,使用cid:logo
作为图像的源。
multipart/alternative
要创建multipart/alternative对象,创建一个MultipartAlternative
实例,添加替代方案,并调用finish()
。添加替代方案有两种方法
addMultipart(Multipart $multipart)
添加另一个multipart作为替代。这通常与multipart/related对象一起使用。addPart($content, $contentType, $contentLength = -1, $contentTransferEncoding = '')
添加给定内容的部分。内容类型和内容是必需的;内容长度是可选的,如果内容是字符串,则将被忽略;内容传输编码是可选的,如果设置了,则用于Content-Transfer-Encoding
头。
示例
// the multipart object can take an optional pre-existing boundary
$multipart = new MultipartAlternative();
// $related is a MultipartRelated instance as created above
$multipart->addPart(file_get_contents('body.txt'), 'text/plain');
$multipart->addMultipart($related);
$multipart->finish();
multipart/mixed
要创建一个multipart/mixed对象,创建一个MultipartMixed
实例,添加部分,并调用finish()
。有三种方法可以添加部分
addMultipart(Multipart $multipart)
添加另一个multipart。这通常用于multipart/alternative或multipart/related对象。addPart($content, $contentType, $contentLength = -1, $contentTransferEncoding = '')
添加一个具有给定内容的部分。这可以用于纯文本电子邮件的主体。内容内容和内容类型是必需的;内容长度是可选的,如果内容是字符串,将忽略它;内容传输编码是可选的,如果设置了,它将被用于Content-Transfer-Encoding
头。addAttachment($filename, $content, $contentType, $contentLength = -1, $contentTransferEncoding = '')
添加一个内容处置为attachment
的部分。文件名、内容和内容类型是必需的;内容长度是可选的,如果内容是字符串,将忽略它;内容传输编码是可选的,如果设置了,它将被用于Content-Transfer-Encoding
头。
示例
// the multipart object can take an optional pre-existing boundary
$multipart = new MultipartMixed();
// $alternative is a MultipartAlternative instance as created above
$multipart->addMultipart($alternative);
// the content length is irrelevant because the content is a string
$multipart->addFile('file.png', base64_encode(file_get_contents('file.png')), 'image/png', -1, 'base64');
$multipart->finish();
multipart内容
部分或文件的内容可以通过以下三种方式之一给出
- 作为字符串。将忽略内容长度。
- 作为可以使用
fread
读取的资源。关闭此资源的责任在于调用者。 - 作为接受长度并返回不超过给定长度的字符串的可调用对象。如果没有更多内容可读,它应返回空字符串。
使用MultipartFormData
对象的示例
// content length is not necessary
$multipart->addFile('file1', 'file.txt', 'Hello World', 'text/plain');
// make sure to close the resource after the request has been sent
$resource = fopen('file.html');
$multipart->addFile('file.html', $resource, 'text/html', filesize('file.html'));
// assume that class MyResource exists and has a function read($length)
$myResource = new MyResource(...);
$multipart->addFile('file.bin', array($myResource, 'read'), 'application/octet-stream');
cURL支持
要使用cURL请求发送multipart对象,需要遵循以下步骤
- 使用
CURLOPT_CUSTOMREQUEST
设置请求类型。 - 将
CURLOPT_UPLOAD
选项设置为true
。 - 将对象的
curl_read
方法设置为CURLOPT_READFUNCTION
。 - 确保设置了
Content-Type
和Content-Length
头。请注意,Content-Length
头是可选的。
例如
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_UPLOAD, true);
curl_setopt($ch, CURLOPT_READFUNCTION, array($multipart, 'curl_read'));
$headers = ['Content-Type: ' . $multipart->getContentType()];
$contentLength = $multipart->getContentLength();
if ($contentLength >= 0) {
$headers[] = 'Content-Length: ' . $contentLength;
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
非流式支持
如果无法进行流式传输(例如,因为需要字符串,如在mail
函数中),可以通过调用buffer
方法在内存中缓冲multipart对象。此方法接受可选的缓冲区大小,并返回缓冲的内容。内容长度将相应设置。请注意,您应该在调用read
(或curl_read
)之前这样做,否则缓冲的内容可能不包含所有所需的内容(特别是如果您正在使用资源或可调用对象)。
Multipart.__toString()
已重写以缓冲multipart对象,因此您可以通过将multipart对象转换为string
来实现相同的效果。区别在于,buffer
需要multipart对象已完成。