使用 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】:

在这个文件中: 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。对于生产,这是评论【参考方案2】:

错误表明您没有在本地安装所需的 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 文件中配置后,我也无法解决它!但许多人认为只有这才是正确的解决方案【参考方案3】:

从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 已被弃用。

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

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

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

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

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

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

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