有没有办法可以使用PHP的内置SoapClient类为请求添加soap附件?看起来它不支持,但也许我可以手动构建mime边界?我知道PEAR SOAP库支持它们,但为了使用它我必须重写我的整个库才能使用它。
答案 0 :(得分:5)
为什么不使用Data URI scheme发送文件而不是实施SoapAttachment?这是一个例子:
客户
$client = new SoapClient(null, array(
'location' => "http://localhost/lab/stackoverflow/a.php?h=none",
'uri' => "http://localhost/",
'trace' => 1
));
// Method 1 Array
// File to upload
$file = "golf3.png";
// First Example
$data = array();
$data['name'] = $file;
$data['data'] = getDataURI($file, "image/png");
echo "Example 1: ";
echo ($return = $client->upload($data)) ? "File Uploaded : $return bytes" : "Error Uploading Files";
// Method 2 Objects
// File to upload
$file = "original.png";
// Second Example
$attachment = new ImageObj($file);
$param = new SoapVar($attachment, SOAP_ENC_OBJECT, "ImageObj");
$param = new SoapParam($param, "param");
echo "Example 2: ";
echo ($return = $client->uploadObj($attachment)) ? "File Uploaded : $return bytes" : "Error Uploading Files";
输出
Example 1: File Uploaded : 976182 bytes
Example 2: File Uploaded : 233821 bytes
服务器强>
class UploadService {
public function upload($args) {
$file = __DIR__ . "/test/" . $args['name'];
return file_put_contents($file, file_get_contents($args['data']));
}
public function uploadObj($args) {
$file = __DIR__ . "/test/" . $args->name;
$data = sprintf("data://%s;%s,%s", $args->mime, $args->encoding, $args->data);
return file_put_contents($file, file_get_contents($data));
}
}
try {
$server = new SOAPServer(NULL, array(
'uri' => 'http://localhost/'
));
$server->setClass('UploadService');
$server->handle();
} catch (SOAPFault $f) {
print $f->faultstring;
}
客户端工具
// Function Used
function getDataURI($image, $mime = '') {
return 'data: ' . (function_exists('mime_content_type') ?
mime_content_type($image) : $mime) . ';base64,' .
base64_encode(file_get_contents($image));
}
// Simple Image Object
class ImageObj{
function __construct($file, $mime = "") {
$this->file = $file;
$this->name = basename($file);
if (function_exists('mime_content_type')) {
$this->mime = mime_content_type($file);
} elseif (function_exists('finfo_open')) {
$this->mime = finfo_file(finfo_open(FILEINFO_MIME_TYPE), $file);
} else {
$this->mime = $mime;
}
$this->encoding = "base64";
$this->data = base64_encode(file_get_contents($file));
}
}
答案 1 :(得分:2)
是的,您可以使用imap_mail_compose等内容构建邮件的MIME组件。
您需要像在第一个示例中那样构造多部分消息,将$request
参数中的XML从重写的SoapClient::__doRequest
方法放入MIME消息的第一部分
然后,您可以按照其他人在第一个imap_mail_compose
示例中显示的内容来添加一个或多个带附件的邮件部分。这些附件可以,但不必是base64编码,它们也可以是二进制。每个部分的编码由特定于部分的标题指定。
根据之前链接的SwA Document @Baba,您还需要制作一组适当的HTTP标头。
一旦完成所有这些,您应该看到类似该文档中的示例:
MIME-Version: 1.0
Content-Type: Multipart/Related; boundary=MIME_boundary; type=text/xml;
start="<claim061400a.xml@claiming-it.com>"
Content-Description: This is the optional message description.
--MIME_boundary
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: 8bit
Content-ID: <claim061400a.xml@claiming-it.com>
<?xml version='1.0' ?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
..
<theSignedForm href="cid:claim061400a.tiff@claiming-it.com"/>
..
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
--MIME_boundary
Content-Type: image/tiff
Content-Transfer-Encoding: binary
Content-ID: <claim061400a.tiff@claiming-it.com>
...binary TIFF image...
--MIME_boundary--
您可以使用上述覆盖的SoapClient::__doRequest
方法通过线路发送。到目前为止,我在尝试实现它时注意到的事情:
href="cid:claim061400a.tiff@claiming-it.com"
imap_mail_compose
返回的MIME内容中提取边界组件,以便在HTTP Content-Type 标头中使用imap_mail_compose
看起来相当小(但悬而未决),如果证明不足,请考虑Mail_Mime而不是内容类型:多部分/相关;边界= MIME_boundary; 类型=文本/ XML;开始= “”
最后,我不确定 SwA 的各种实现在互联网上有多均匀...只需说,我无法上传到远程服务,粗略实现了我上面所描述的内容。看起来似乎 SwA 是典型的SOAP附件范例,不过我在网上阅读的内容。