On Friday I finally cracked a PHP problem that had been plaguing one of my applications. The problem was actually kind of simple in retrospect. I had to have my script send an email with an attachment. No biggie, right? Well, easier said then done at least. So had my script all set up and the emails were sending out perfectly, except Outlook couldn’t didn’t receive the attachements. (Pine could though!) After a couple of days of arguing with the code, I cleared my head and sent myself an email with Outlook and there was the solution. It seems that all of the guides that tell you how to use PHP’s mail function to send an attachment have Content-type: multipart/alternative in the header, which isn’t technically wrong, but really doesn’t work. All it takes is some simple thoughts (which were obviously beyond me at the time) to figure out that alternative means exactly that and mixed, means many types in the one message. Here’s the script I ended up with:


<?
   $files = array(“/path/to/file1.jpg”, “http://www.url.com/to/file2.jpg”);
   
$boundary = “[” . md5(time()) . “]”;

   foreach ($files AS $file) {
      
$dr++;
      
$downfile = file_get_contents($file);
      
$enc = chunk_split(base64_encode($downfile));

      $glue = “–” . $boundary . “n”;
      
$glue .= “Content-Type: image/jpeg; name=”page” . $dr . “.jpg”n”;
      
$glue .= “Content-Transfer-Encoding: base64n”;
      
$glue .= “Content-Disposition: attachment; filename=”page” . ($dr + 1) . “.jpg”nn”;
      
$glue .= $enc . “nn”;

      $attachments[] = $glue;
   }

   $headers = “From: ” . stripslashes($_REQUEST[“from”]) . “n”;
   
$headers .= “MIME-Version: 1.0n”;
   
$headers .= “Content-type: multipart/mixed; boundary=”” . $boundary . “”n”;

   $msg = “This is a multi-part message in MIME format.nn”;
   
$msg .= “–” . $boundary . “n”;
   
$msg .= “Content-Type: text/plain; charset=”iso-8859-1″n”;
   
$msg .= “Content-Transfer-Encoding: 7bitnn”;
   
$msg .= stripslashes($_REQUEST[“message”]) . “nn”;

   $msg .= implode(“”, $attachments);

   $msg .= “–” . $boundary . “–n”;
      
   
mail(stripslashes($_REQUEST[“to”]), stripslashes($_REQUEST[“subject”]), $msg, $headers);
?>


     I was using it to send jpegs but the code could be adapted for anything. Also, if you wanted the body of the message to be either HTML or plain text, you could make the body’s content type multipart/alternative and have it’s own boundary, then in each parts of the body one would be text/html and the other text/plain. I know there’s some scripts that I need to update in the nearer future now too, like my web mail program which hasn’t really been working right since I moved it to my terabyte.

Author: Ian

Share This Post On

Submit a Comment

Your email address will not be published. Required fields are marked *