使用phpmailer发送带有动态附件(pdf)的邮件会在pdf中返回错误

使用phpmailer发送带有动态附件(pdf)的邮件会在pdf中返回错误,php,mysqli,phpmailer,Php,Mysqli,Phpmailer,我附上并发送发票pdf使用php邮件 这是我用来发送邮件的 $string = file_get_contents("http://website.com/page/pdf_vouch.php&pvno=$pv&mnth=$mnth&yr=$yr&email=$email&final=$final&name=$ms_n"); $mail->AddStringAttachment($string, "sales_invoice.pdf",

我附上并发送发票pdf使用php邮件

这是我用来发送邮件的

$string = file_get_contents("http://website.com/page/pdf_vouch.php&pvno=$pv&mnth=$mnth&yr=$yr&email=$email&final=$final&name=$ms_n"); 

$mail->AddStringAttachment($string, "sales_invoice.pdf", $encoding = 'base64', $type = 'application/pdf');
通过这个,我将一些值发送到一个特定的页面,该页面将生成pdf,并将通过电子邮件发送生成的pdf作为附件

问题在于name参数。当我仅以字符串形式给出名称时,将发送带有附件的邮件,并且可以打开pdf。但如果它是一个变量,那么邮件将被发送,但pdf将不会打开,并显示一些错误,如未正确解码

我正在从数据库中获取name变量


谁能告诉我可能的问题是什么。

由于PHPMailer无法自动获取远程内容,您需要自己完成

所以你说:

// we can use file_get_contents to fetch binary data from a remote location
$url = 'http://website.com/page/pdf_vouch.php&pvno=$pv&mnth=$mnth&yr=$yr&email=$email&final=$final&name=$ms_n';
$binary_content = file_get_contents($url);

// You should perform a check to see if the content
// was actually fetched. Use the === (strict) operator to
// check $binary_content for false.
if ($binary_content) {
   throw new Exception("Could not fetch remote content from: '$url'");
}

// $mail must have been created
$mail->AddStringAttachment($binary_content, "sales_invoice.pdf", $encoding = 'base64', $type = 'application/pdf');

// continue building your mail object...

使用
$mail->addAttachment
而不是
$mail->addStringAttachment

您需要对URL中嵌入的任何参数进行URL编码:

$string = file_get_contents(
    "http://website.com/page/pdf_vouch.php&pvno=".rawurlencode($pv).
    "&mnth=".rawurlencode($mnth).
    "&yr‌​=‌".rawurlencode(​$yr).
    "&email=".rawurlencode($email).
    "&final=".rawurlencode($final).
    "&name=".rawurlencode($ms_n)
);
urlencode()
产生Javascript风格的编码,使用
+
对空格进行编码,在向用户显示URL的地方,空格的可读性稍高一些,但当所有内容都发生在后端时(如本例中),这不成问题。要获得更健壮的编码,请使用
rawurlencode()
,它将空格编码为
%20

当您的变量可能包含URL中有意义的字符时,正确的编码尤其重要,我怀疑这是您遇到的问题-例如,如果
$final
包含
&name=foo
,如果未编码,则会导致与真实的
name
参数混淆

如果您已经验证了其中一些,则可以跳过它们(例如,如果您已经知道
$yr
仅包含数字)


如果您提供了嵌入到URL中的变量的示例值,那么回答这个问题会更快。

这是错误的。URL不返回文件名,而是返回内容,因此
addStringAttachment
是正确的。在URL参数中添加引号没有任何区别。你怎么能对引号如此确定?因为OP在键入name参数时没有问题,所以引号可以保存他。公平地说,OP没有给出name值的示例,所以我们不能确定,但是像这样引用URL参数是极不寻常的,不管怎样,变量是否需要URL编码也没什么区别。为什么要在评论中加入关于检查严格相等性的内容,但不这样做呢?当然,但是发布不可能工作的代码并不是回答这个问题的好方法。为什么他不应该这样做?他附加的不是字符串,而是文件。他不是-URL以字符串形式返回PDF内容。它没有文件名,没有存储在磁盘上,它只是一个字符串变量。我假设您指的是
文件中的
$name
变量\u get\u contents
调用-如果您给出一个
$name
使用的值示例,会有所帮助。所有这些变量都在URL中使用,因此它们需要URL转义(例如使用
rawurlencode()
)才能可靠地工作。正确的调试方法是在尝试通过电子邮件发送文件之前检查
file\u get\u contents
调用的返回值;那么您一次只能调试一件事情。首先,我感谢所有对这个问题发表评论的人。我解决了。正如您所说,我尝试了使用
rawurlencode()
,但在OP中没有任何区别。名称之间的空格是问题所在。我刚刚用字符
+
替换了空格,效果很好。现在我可以打开并查看附件了。遗憾的是,我没有注意到空间的事情,而是将名称从url粘贴到
文件\u get\u contents
。呃,你所做的是对空间进行url编码。听起来你没有正确使用rawurlencode。更换空间不足以使其可靠。你应该像我最初建议的那样,对所有变量进行url编码,而不仅仅是名称。但是如果名称变量本身造成了问题,那么对名称变量进行url编码应该可以正常工作吗?我喜欢这样,
$string=file\u get\u contents(“http://website.com/page/pdf_vouch.php&pvno=$pv&mnth=$mnth&yr=$yr&email=$email&final=$final&name=urlencode($ms_n)”)
;不,字符串中的函数不求值。这样做:
文件获取内容(“http://website.com/page/pdf_vouch.php&pvno=$pv&mnth=$mnth&yr=‌​$yr&email=$email&final=$final&name=“.urlencode($ms_n))