如何使用PHP在电子邮件正文中发送base64图片?

3
我正在尝试使用以下PHP代码发送带有base64图像的电子邮件正文,但图像从未出现...如果我更改为URL,则可以正常工作,但是使用base64则不能...我在新页面上仅使用<img src=base64>测试了base64并成功了...我错过了什么吗?
<?php
    // recipients
    $to  = $_POST['email'];

    // subject
    $subject = 'Test';

    // message
    $message = '
        <html>
        <head>
         <title>Test</title>
        </head>
        <body>

            <img src="'.$_POST['imageFromOtherPage'].'"/>

        </body>
        </html>
        ';

    // To send HTML mail, the Content-type header must be set
    $headers  = 'MIME-Version: 1.0' . "\r\n";
    $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";

    // Mail it
    mail($to, $subject, $message, $headers);
 ?>

这是我的base64图片示例:http://jsfiddle.net/28nP4/

5个回答

7
我尝试了不同的方法,唯一找到的方法是上传图像并获取URL,我从这个链接中得到了它:http://j-query.blogspot.in/2011/02/save-base64-encoded-canvas-image-to-png.html 非常简单:
<?php
    // requires php5
    define('UPLOAD_DIR', 'images/');
    $img = $_POST['img'];
    $img = str_replace('data:image/png;base64,', '', $img);
    $img = str_replace(' ', '+', $img);
    $data = base64_decode($img);
    $file = UPLOAD_DIR . uniqid() . '.png';
    $success = file_put_contents($file, $data);
    print $success ? $file : 'Unable to save the file.';
?>

这将生成一个URL,所以,不再使用<img src="'.$_POST['imageFromOtherPage'].'"/>,而是使用生成的URL。完美地解决了问题!


1
我有同样的问题,最终解决了。这可能对你有帮助:你可以使用SwiftMailer,但必须添加新的Image TextHeader 'Content-Location'。以下是代码:
$message = \Swift_Message::newInstance()->setSubject($subject)->setFrom($fromEmail, 'Name')->setTo($toEmail)->setBcc($bccEmails);
/*get uniqueID from cid:uniqueID */
$imageID = explode(':', $message->embed(\Swift_Image::fromPath('pathToTheImage')->setContentType('image/png')))[1];

/*Add Content-Location to image header*/
/** @var \Swift_Image $image */
$image = $message->getChildren()[0];
$image->getHeaders()->addTextHeader('Content-Location', $imageID);
$message->setBody('here you will have some html with <img src=$imageID alt="Embed Image">', 'text/html');

$mailer->send($message);

1

获取所有图片URL的函数:

function getImagesFromMsg($msg, $tmpFolderPath)
{
    $arrSrc = array();
    if (!empty($msg))
    {
        preg_match_all('/<img[^>]+>/i', stripcslashes($msg), $imgTags);

        //All img tags
        for ($i=0; $i < count($imgTags[0]); $i++)
        {
            preg_match('/src="([^"]+)/i', $imgTags[0][$i], $withSrc);
            //Remove src
            $withoutSrc = str_ireplace('src="', '', $withSrc[0]);

            //data:image/png;base64,
            if (strpos($withoutSrc, ";base64,"))
            {
                //data:image/png;base64,.....
                list($type, $data) = explode(";base64,", $withoutSrc);
                //data:image/png
                list($part, $ext) = explode("/", $type);
                //Paste in temp file
                $withoutSrc = $tmpFolderPath."/".uniqid("temp_").".".$ext;
                @file_put_contents($withoutSrc, base64_decode($data));
            }

            //Set to array
            $arrSrc[] = $withoutSrc;
        }
    }
    return $arrSrc;
}

我正在使用这个修改过的版本,我检查了模板的主体,并且我使用了http://swiftmailer.org/docs/messages.html中的$message->embed,然后我用此函数创建的文件的cid替换了src="X"的内容...非常好用!谢谢! - Benjamin Vison

0
<img src="'.$_POST['imageFromOtherPage'].'"/>

您的POST请求需要以data:image/png;base64,开头以形成base64编码的data: URI

但即使您修复了这个问题,您在查看消息的电子邮件客户端可能根本不支持该方法。data:URI是一个相对较新的现象 - 至少在电子邮件客户端的时间线上是如此,其中大多数仍在发现有一种名为CSS的技术。在电子邮件中使用图像的经过验证的方法是将图像作为内联附件嵌入。

以下是一些不依赖于库的方法:使用PHP发送带有内联图像附件的电子邮件

然而,使用像Swiftmailer这样的库可能会减轻很多痛苦。这里是适当的Swiftmailer文档。


0
尝试测试 $_POST['imageFromOtherPage'] 是否包含 base64,可能代码太长无法使用 Post,您需要使用 php://input

我进行了测试,将内容写在<P>标签中,并展示了正确的base64内容...但它无法作为图像"翻译"。 - CarinaPilar
你确定它显示了所有的数据吗?图片的大小是多少?如果它超过1MB,那么帖子可能会截断base64的一部分。 - Renato Probst

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接