使用 Mandrill (php) 发送电子邮件时出错

Posted

技术标签:

【中文标题】使用 Mandrill (php) 发送电子邮件时出错【英文标题】:error in send email using Mandrill (php) 【发布时间】:2013-10-13 21:24:34 【问题描述】:

我是第一次使用 mandrill api。我正在使用以下代码。 我有 Mandrill API 密钥。

 <?php
    try 
        $mandrill = new Mandrill('YOUR_API_KEY');
        $message = array(
            'html' => '<p>Example HTML content</p>',
            'text' => 'Example text content',
            'subject' => 'example subject',
            'from_email' => 'message.from_email@example.com',
            'from_name' => 'Example Name',
            'to' => array(
                array(
                    'email' => 'recipient.email@example.com',
                    'name' => 'Recipient Name'
                )
            ),
            'headers' => array('Reply-To' => 'message.reply@example.com'),
            'important' => false,
            'track_opens' => null,
            'track_clicks' => null,
            'auto_text' => null,
            'auto_html' => null,
            'inline_css' => null,
            'url_strip_qs' => null,
            'preserve_recipients' => null,
            'view_content_link' => null,
            'bcc_address' => 'message.bcc_address@example.com',
            'tracking_domain' => null,
            'signing_domain' => null,
            'return_path_domain' => null,
            'merge' => true,
            'global_merge_vars' => array(
                array(
                    'name' => 'merge1',
                    'content' => 'merge1 content'
                )
            ),
            'merge_vars' => array(
                array(
                    'rcpt' => 'recipient.email@example.com',
                    'vars' => array(
                        array(
                            'name' => 'merge2',
                            'content' => 'merge2 content'
                        )
                    )
                )
            ),
            'tags' => array('password-resets'),
            'subaccount' => 'customer-123',
            'google_analytics_domains' => array('example.com'),
            'google_analytics_campaign' => 'message.from_email@example.com',
            'metadata' => array('website' => 'www.example.com'),
            'recipient_metadata' => array(
                array(
                    'rcpt' => 'recipient.email@example.com',
                    'values' => array('user_id' => 123456)
                )
            ),
            'attachments' => array(
                array(
                    'type' => 'text/plain',
                    'name' => 'myfile.txt',
                    'content' => 'ZXhhbXBsZSBmaWxl'
                )
            ),
            'images' => array(
                array(
                    'type' => 'image/png',
                    'name' => 'IMAGECID',
                    'content' => 'ZXhhbXBsZSBmaWxl'
                )
            )
        );
        $async = false;
        $ip_pool = 'Main Pool';
        $send_at = 'example send_at';
        $result = $mandrill->messages->send($message, $async, $ip_pool, $send_at);
        print_r($result);

     catch(Mandrill_Error $e) 
        echo 'A mandrill error occurred: ' . get_class($e) . ' - ' . $e->getMessage();

        throw $e;
    
    ?>

通过使用此代码,我收到以下错误:

发生 mandrill 错误:Mandrill_HttpError - API 调用消息/发送失败:错误设置证书验证位置:CAfile:/usr/local/share/certs/ca-root-nss.crt CApath:无

为什么会出现此错误?

【问题讨论】:

Simple php function to send an email with Mandrill的可能重复 【参考方案1】:

从http://curl.haxx.se/docs/caextract.html 下载 cacert.pem 并将其放在我的服务器上后,我能够通过以下方式解决此问题(同时确保一切安全):

$mandrill = new Mandrill(MANDRILL_API_KEY);

// Fix CA issue
curl_setopt($mandrill->ch, CURLOPT_SSL_VERIFYHOST, true);
curl_setopt($mandrill->ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($mandrill->ch, CURLOPT_CAINFO, 'PATH_TO/cacert.pem');

Mandrill 类中的 curl 属性是公共的,因此无需向库本身添加 hack。

【讨论】:

这对我有用,但是,JFYI,CURLOPT_SSL_VERIFYHOST 应该设置为 2 而不是 true,true 已被弃用。【参考方案2】:

在这个文件中: mandrill-api-php\src\Mandrill.php

在第 58 行初始化 curl:

$this->ch = curl_init();

你需要添加这两个选项来解决问题:

curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0);

或者您可以选择: HTTPS and SSL3_GET_SERVER_CERTIFICATE:certificate verify failed, CA is OK

【讨论】:

这没有帮助...... . 如果您将这两个选项设置为 0,您实际上是在关闭 SSL 验证,这会给您带来潜在的安全漏洞,绝对不推荐。 我只在 localhost 中使用它,因为我无法在 Windows 上使用 cert。对于生产,这是评论【参考方案3】:

错误表明您没有在本地安装所需的 SSL 证书来验证与 Mandrill 的 API 的 SSL 连接。您可以通过操作系统的包管理器获取证书包,也可以下载与 Mozilla 一起分发的包:http://curl.haxx.se/docs/caextract.html,然后将它们存储在本地。

【讨论】:

下载证书后,在PHP.ini中添加: curl.cainfo = "PATH_TO/cacert.pem" 下载 pem 文件并将 curl.cainfo = c:\wamp\cacert.pem 添加到 php.ini 后,我仍然遇到同样的错误 不知何故,即使在下载认证并在正确的 php.ini 文件中配置后,我也无法解决它!但许多人认为只有这才是正确的解决方案

以上是关于使用 Mandrill (php) 发送电子邮件时出错的主要内容,如果未能解决你的问题,请参考以下文章

使用 PHP 使用 Mandrill 发送电子邮件

使用模板发送电子邮件 (Mandrill PHP)

使用 Mandrill api 更改格式发送邮件

使用 smtp mandrill 发送电子邮件的问题

使用 Mandrill 发送电子邮件模板给我错误

Codeigniter 和 Mandrill api,无法发送电子邮件