CodeIgniter的邮件库发送带有空附件的邮件

时间:2016-09-25 18:34:19

标签: php codeigniter email

我正在使用CodeIgniter的电子邮件库向我自己发送邮件进行测试。此电子邮件应该有附件,因此我使用以下代码发送邮件:

$this->load->library('colorparser');
$this->load->library('email');

$config = array();
$config['mailtype'] = 'html';

$this->email->initialize($config);

$this->email->from('...', '...');
$this->email->to('...');

$this->email->subject('A user sent in a map for your Trackmania tournament');
$this->email->message("some HTML code");
$this->email->attach("/www/htdocs/.../dev/tournois/uploads/tm2/57e30c92aaa65393755646.gif", 'attachment');

$this->email->send();

让我感到好奇的是,执行后我收到一封带附件的邮件。名称是正确的,Thunderbird尝试显示gif,但附件为空,0字节。

然后我尝试通过print_debugger()获得输出,效果很好。我在调试器显示的信息中看不到任何错误,即使是base64编码的东西也存在。

你知道为什么会这样吗?

2 个答案:

答案 0 :(得分:1)

一切看起来都不错,所以要仔细检查一下可能会有所帮助。

  1. 正确设置了文件权限(尝试777只是为了确保然后根据需要减少)
  2. 路径名称是正确的。您也可以尝试使用URL而不是路径名来测试它是否是路径名。
  3. 配置包含.gif作为允许的文件类型忽略那个,让我自己感到困惑的文件上传。
  4. 文件实际存在且不为空白。
  5. 如果您是动态创建文件或上传文件,那么可能会在那里发生错误,而不是在电子邮件中。

    希望有所帮助。

答案 1 :(得分:1)

我重新分析了邮件标题&尸体并发现了一条缺失的空白行,这就是问题所在:

Content-Type: image/gif; name="57e30c92aaa65393755646.gif"
Content-Disposition: attachment;
Content-Transfer-Encoding: base64
R0lGODlhLAGoAPcAADwkGEAnHEMpIEQsIEQtJEgxJks1K082KVM4KVQ9KlQ8Lk85MVI9NFQ/N1JA...

但通常必须有两个换行符:

Content-Type: image/gif; name="57e30c92aaa65393755646.gif"
Content-Disposition: attachment;
Content-Transfer-Encoding: base64

R0lGODlhLAGoAPcAADwkGEAnHEMpIEQsIEQtJEgxJks1K082KVM4KVQ9KlQ8Lk85MVI9NFQ/N1JA...

我不知道这是否已在较新的CodeIgniter构建中修复,但对于每个遇到相同问题的人,您可以通过自己编辑电子邮件库来修复它。该库位于/system/libraries文件夹中。您也可以覆盖它(使用MY _...),但为了简单修复它,我只是在CI库中的代码中添加了第二个“新行”。

这是CodeIgniter为邮件添加附件的原始功能:

protected function _append_attachments(&$body, $boundary, $multipart = null)
{
    for ($i = 0, $c = count($this->_attachments); $i < $c; $i++)
    {
        if (isset($multipart) && $this->_attachments[$i]['multipart'] !== $multipart)
        {
            continue;
        }

        $name = isset($this->_attachments[$i]['name'][1])
            ? $this->_attachments[$i]['name'][1]
            : basename($this->_attachments[$i]['name'][0]);

        $body .= '--'.$boundary.$this->newline
            .'Content-Type: '.$this->_attachments[$i]['type'].'; name="'.$name.'"'.$this->newline
            .'Content-Disposition: '.$this->_attachments[$i]['disposition'].';'.$this->newline
            .'Content-Transfer-Encoding: base64'.$this->newline
            .(empty($this->_attachments[$i]['cid']) ? '' : 'Content-ID: <'.$this->_attachments[$i]['cid'].'>'.$this->newline.$this->newline)
            .$this->_attachments[$i]['content'].$this->newline;
    }

    // $name won't be set if no attachments were appended,
    // and therefore a boundary wouldn't be necessary
    empty($name) OR $body .= '--'.$boundary.'--';
}

现在,要解决此问题,只需使用新行替换Content ID字符串部分的'',因此如果没有Content ID,则会缺少新行。

$body .= '--'.$boundary.$this->newline
                .'Content-Type: '.$this->_attachments[$i]['type'].'; name="'.$name.'"'.$this->newline
                .'Content-Disposition: '.$this->_attachments[$i]['disposition'].';'.$this->newline
                .'Content-Transfer-Encoding: base64'.$this->newline
                .(empty($this->_attachments[$i]['cid']) ? $this->newline : 'Content-ID: <'.$this->_attachments[$i]['cid'].'>'.$this->newline.$this->newline)
                .$this->_attachments[$i]['content'].$this->newline;

希望这有助于某人!