Asked  8 Months ago    Answers:  5   Viewed   36 times

I'm a bit worried if this function sends emails that can be recognized correctly on the majority of email and webmail clients the way it should, specifically I'm most concerned about this doubts:

  • Are the UTF-8 declarations and attachments well formed?
  • Do I need to use quoted_printable_decode()? If yes, where?
  • Content-Transfer-Encoding: 7 or 8 bits? I've always seen 7 but since I'm sending a UTF-8 encoded mail I'm not sure.
  • Should I use mb_send_mail() or mail() is enough?

EDIT: I don't know why but the code is not showing up correctly, I made it available @ http://gist.github.com/104818

EDIT 2: I'm aware of other alternatives (libraries) for email handling, but for the sake of my own curiosity and knowledge I just wish to know if this code is 100% good, or if it's buggy.

function Email($name, $from, $to, $subject, $message, $bcc = null, $attachments = null)
{
    ini_set('SMTP', 'localhost');
    ini_set('sendmail_from', $from);

    $name = filter_var($name, FILTER_SANITIZE_STRING);
    $from = filter_var($from, FILTER_SANITIZE_EMAIL);
    $subject = filter_var($subject, FILTER_SANITIZE_STRING);

    $boundary = '_Boundary_' . md5(microtime(true) . mt_rand(0, PHP_INT_MAX));

    $headers = array
    (
        'MIME-Version: 1.0',
        'Content-Type: multipart/mixed; boundary="Mixed' . $boundary . '"',
        'Date: ' . date('r', time()),
        'From: "' . $name . '" <' . $from . '>',
        'Reply-To: "' . $name . '" <' . $from . '>',
        'Return-Path: "' . $name . '" <' . $from . '>',
        'X-Mailer: PHP ' . phpversion(),
        'X-Priority: 2',
        'X-MSMail-Priority: High',
        'X-Originating-IP: ' . $_SERVER['SERVER_ADDR'],
    );

    if (is_null($to) === false)
    {
        if (is_array($to) === false)
        {
            $to = explode(',', $to);
        }

        foreach ($to as $key => $value)
        {
            $to[$key] = filter_var($value, FILTER_SANITIZE_EMAIL);
        }

        $to = implode(', ', array_filter($to));
    }

    if (is_null($bcc) === false)
    {
        if (is_array($bcc) === false)
        {
            $bcc = explode(',', $bcc);
        }

        foreach ($bcc as $key => $value)
        {
            $bcc[$key] = filter_var($value, FILTER_SANITIZE_EMAIL);
        }

        $headers[] = 'BCC: ' . implode(', ', array_filter($bcc));
    }

    if (is_null($attachments) === false)
    {
        settype($attachments, 'array');

        foreach ($attachments as $key => $value)
        {
            if (is_file($value) === true)
            {
                $attachments[$key] = array
                (
                    '',
                    '--Mixed' . $boundary,
                    'Content-Type: application/octet-stream; name="' . basename($value) . '"',
                    'Content-Disposition: attachment; filename="' . basename($value) . '"',
                    'Content-Transfer-Encoding: base64',
                    '',
                    trim(chunk_split(base64_encode(file_get_contents($value)))),
                );

                $attachments[$key] = implode("n", $attachments[$key]);
            }

            else
            {
                unset($attachments[$key]);
            }
        }

        $attachments = implode("n", $attachments) . "n";
    }

    $message = array
    (
        'This is a multi-part message in MIME format.',
        '',
        '--Mixed' . $boundary,
        'Content-Type: multipart/alternative; boundary="Alt' . $boundary . '"',
        '',
        '--Alt' . $boundary,
        'Content-Type: text/plain; charset="UTF-8"',
        'Content-Disposition: inline',
        'Content-Transfer-Encoding: 8bit',
        '',
        trim(strip_tags($message, '<a>')),
        '',
        '--Alt' . $boundary,
        'Content-Type: text/html; charset="UTF-8"',
        'Content-Disposition: inline',
        'Content-Transfer-Encoding: 8bit',
        '',
        trim($message),
        '',
        '--Alt' . $boundary . '--',
        $attachments,
        '--Mixed' . $boundary . '--',
    );

    if (@mail($to, stripslashes($subject), implode("n", $message), implode("n", $headers)) === true)
    {
        return true;
    }

    return false;
}

 Answers

23

While that should work, I would strongly recommend using a prebuilt Mail/SMTP class such as Zend_Mail. While I don't think the whole Zend Framework is the cat's pajamas, I do have a very good opinion of their mail handling code.

EDIT: I should also add that using a prebuilt Mail/SMTP class will abstract almost all of the complexity/structure of multi-part emails.

Update 2009-05-06: Answering your question directly.

  • Are the UTF-8 declarations and attachments well formed?

They look decent enough.

  • Do I need to use quoted_printable_decode()? If yes, where?

No. You would want to use quoted_printable_decode() only if you are decoding an email message. Not when you are encoding one. Should you use quoted_printable_encode()? I will discuss this next.

  • Content-Transfer-Encoding: 7 or 8 bits? I've always seen 7 but since I'm sending a UTF-8 encoded mail I'm not sure.

Only use 8bit encoding if you know that the destination SMTP server can support it. However, since you are passing your email off to the local MTA, I wouldn't recommend setting this value. The default value is 7bit encoding, but it has it's own set of restrictions: up to 998 octets per line of the code range 1-127 with CR and LF only allowed to appear as part of the CRLF line ending (http://tools.ietf.org/html/rfc2045#section-2.7).

I would recommend you use the Quoted-Printable (http://tools.ietf.org/html/rfc2045#section-6.7) Content-Transfer-Encoding. Where you are calling trim(strip_tags($message, '<a>')) and trim($message) you will want to enclose those with quoted_printable_encode(trim(...)).

  • Should I use mb_send_mail() or mail() is enough?

If you know you are not going to be handling Multibyte messages (Japanese, Korean, Chinese, etc.) then mail() should suffice.

Now that I've answered your initial questions, let me tell you where some problems exist.

  1. You are specifying that the Character set of your Plain Text and Html content parts are UTF-8, however it doesn't appear as you are actually ensuring that they really are UTF-8 encoded.
  2. You are checking for null in $to, $bcc, $attachments before you further process them, however, you aren't doing anything when they may actually be null. So, if you happen to receive a null for $to, you don't process the variable, but you continue to send an email to null.

As of right now, that's all I am going to go into but I am still going to highly recommend a pre-built solution as they have had lots of users/time to work out bugs.

Wednesday, March 31, 2021
 
TheFrack
answered 8 Months ago
15

If you use utf-8 try this:

<?php $subject = "=?UTF-8?B?" . base64_encode($subject) . "?="; ?>
Wednesday, March 31, 2021
 
brombeer
answered 8 Months ago
52

Swiftmailer

It's awesome! I've used it in all my projects with great results!

About the mail going to spam, I suggest this article

Wednesday, March 31, 2021
 
Easen
answered 8 Months ago
67

If you are using to send form using php then below is right way:

 //search form
    <form action="category.php?type=search" method="post">

    </form>

//select all delete form  

    <form name="frmMain" method="post">

    </form>

if you want to send form using ajax and jquery then you can use this way:

//search form
<form action="category.php?type=search" method="post">

  //select all delete form  
   <form name="frmMain" method="post">

  </form>
</form>

Example of HTML:5 new form element (from an answer by ilevent):

<form id="saveForm" action="/post/dispatch/save" method="post"></form>
<form id="deleteForm" action="/post/dispatch/delete" method="post"></form>

<div id="toolbar">
 <input type="text" name="foo" form="saveForm" />
 <input type="hidden" value="some_id" form="deleteForm" />
 <input type="text" name="foo2" id="foo2" form="saveForm" value="success" />

    <input type="submit" name="save" value="Save" form="saveForm" onclick="alert(document.getElementById('deleteForm').elements.length + ' ' + document.getElementById('saveForm').elements.length + ' ' + document.getElementById('saveForm').elements['foo2'].value);return false;" />
    <input type="submit" name="delete" value="Delete" form="deleteForm" />
    <a href="/home/index">Cancel</a>
</div>
Saturday, May 29, 2021
 
keisar
answered 5 Months ago
50

Your editor treats the file as UTF-8, so it shows

my $subject = "Änderungen";

Perl effectively treats the file as iso-8859-1, so it sees

my $subject = "Ã?nderungen";

Tell Perl you encoded your script using UTF-8 by adding

use utf8;
Sunday, August 29, 2021
 
bumperbox
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :