How to get email and their attachments from PHP
Asked Answered
I

7

18

I'm writing a photo gallery webapp for a friend's wedding and they want a photo gallery for guests to submit the digital photos they take on the day.

After evaluating all the options, I've decided the easiest thing for users would be to let them use a familiar interface (their email) and just have them send in the pictures as attachments.

I've created an mailbox but now I need to connect and retrieve these attachments for automated processing for adding to the gallery system. But how? Are there any tutorials or prefab classes you've seen for doing this?

Idiocrasy answered 22/9, 2008 at 13:49 Comment(0)
H
4

What MTA are you using? If you use postfix + maildrop you can create a filtering rule that pipes certain messages through a PHP script that then handles the incoming mails. (google for maildrop and xfilter).

Hemmer answered 22/9, 2008 at 13:54 Comment(2)
Yeah postfix-routing looks like a good solution from where I'm sitting. Thanks!Idiocrasy
This is way more elegant but my host doesn't seem to support it. Looks like this is built in with hosts that use cPanel (Maybe its time to find another host)Note
F
10

I used to do a lot of this before, but I can't find the code, here's a scaled down version I found. It should put you on the correct path. I used to run this type of script from a cronjob. Sorry I can't find the final version. ;(

// Open pop mailbox
if (!$mbox = imap_open ("{localhost:110/pop3/notls}INBOX", "user", "tester")) {
  die ('Cannot connect/check pop mail! Exiting');
}

if ($hdr = imap_check($mbox)) {
  $msgCount = $hdr->Nmsgs;
} else {
  echo "Failed to get mail";
  exit;
}

$MN=$msgCount;
$overview=imap_fetch_overview($mbox,"1:$MN",0);

for ($X = 1; $X <= $MN; $X++) {

  $file = imap_fetchbody($mbox, $X, 1);

  imap_delete($mbox, $X);
}

imap_expunge($mbox);
imap_close($mbox);

Good luck!

Frumentaceous answered 22/9, 2008 at 14:3 Comment(1)
If they control the receiving MTA I believe it's more elegant to have the MTA deliver to the program, instead of to an IMAP server, because it's simply fewer points of failure. That's not always an option, I concede.Garnish
G
6

If you're creating a dedicated mailbox for this purpose, using a filtering mechanism is almost definitely not what you want. Instead, you want to have the mailbox be a pipe to the application, and have the application simply read in the message from stdin, parse out the body, and MIME parse the body to get the attachments.

Having a mailbox be a pipe is supported by all the popular unix-based MTAs that I know of, such as sendmail, postfix, and qmail. Generally you define it in your aliases file, like so:


# sendmail or postfix syntax
msgsubmit: "| /usr/bin/php ~path/to/example.php"

Then mails to msgsubmit@ get routed to a php program for delivery.

This has the advantage of not relying on an IMAP server or any other server beyond the MTA being alive, and it works fine as long as you have control over the MTA of the destination host. Filtering is what you'd want if you wanted all messages on a system to be inspected by the script, which I'm guessing is not the case.

If you want a copy kept in a mailbox somewhere (not a bad idea) simply define the alias to go to multiple addresses, like so:


msgsubmit: "| /usr/bin/php ~path/to/example.php", msgsubmit-box

Or postfix virtual format:


msgsubmit
    "| /usr/bin/php ~path/to/example.php"
    msgsubmit-box

Garnish answered 22/9, 2008 at 14:11 Comment(0)
H
6

Have you considered using Google's Picasa Web Albums? You can set up an email address to send photos to and share them online. You can then get an RSS feed of these photos, which most programmers are more familiar with than MTAs.

Humpback answered 22/9, 2008 at 14:14 Comment(2)
This is a neat alternative! Google advises against sharing your secret key, however, so you might want to shroud it by having your MTA alias a certain address to it, with something like this in your alias file: msgsubmit: [email protected]Garnish
plus one to you for thinking outside the boxVentilator
H
4

What MTA are you using? If you use postfix + maildrop you can create a filtering rule that pipes certain messages through a PHP script that then handles the incoming mails. (google for maildrop and xfilter).

Hemmer answered 22/9, 2008 at 13:54 Comment(2)
Yeah postfix-routing looks like a good solution from where I'm sitting. Thanks!Idiocrasy
This is way more elegant but my host doesn't seem to support it. Looks like this is built in with hosts that use cPanel (Maybe its time to find another host)Note
H
1

I think you want a MIME message parser.

I've used this one before and it seems to work fine, although I haven't tested it on really big attachments (i.e. 2-3MB files you might get from digital cameras).

Have you already got a system for reading POP3 / IMAP mailboxes? There is another class on the same site which also works on POP3 (I believe there is also an IMAP one) - however if you will be downloading a fair volume maybe you'll want to investigate a few C-based solutions as I believe that one is pure PHP.

Hexone answered 22/9, 2008 at 13:53 Comment(0)
O
0

Majordomo, could be an alternative to handle emails, but there are some limitations on file attachment handling.

Ormazd answered 6/10, 2012 at 21:46 Comment(0)
F
-4
<?php
//make sure that submit button name is 'Submit'
if(isset($_POST['Submit'])){


       $name = $_POST['visitorname'];
       $email = $_POST['visitoremail'];
       $message = $_POST['visitormessage'];


            $to="[email protected]";

          $subject="From ".$name;


          $from = $email;

          // generate a random string to be used as the boundary marker
          $mime_boundary="==Multipart_Boundary_x".md5(mt_rand())."x";

          // now we'll build the message headers
          $headers = "From: $from\r\n" .
          "MIME-Version: 1.0\r\n" .
             "Content-Type: multipart/mixed;\r\n" .
             " boundary=\"{$mime_boundary}\"";

          // next, we'll build the invisible portion of the message body
          // note that we insert two dashes in front of the MIME boundary
          // when we use it
          $message = "This is a multi-part message in MIME format.\n\n" .
             "--{$mime_boundary}\n" .
             "Content-Type: text/plain; charset=\"iso-8859-1\"\n" .
             "Content-Transfer-Encoding: 7bit\n\n" .
          $message . "\n\n";

 foreach($_FILES as $userfile)
          {
             // store the file information to variables for easier access
             $tmp_name = $userfile['tmp_name'];
             $type = $userfile['type'];
             $name = $userfile['name'];
             $size = $userfile['size'];



             // if the upload succeded, the file will exist
             if (file_exists($tmp_name))
             {

                // check to make sure that it is an uploaded file and not a system file
                if(is_uploaded_file($tmp_name))
                {

                   // open the file for a binary read
                   $file = fopen($tmp_name,'rb');

                   // read the file content into a variable
                   $data = fread($file,filesize($tmp_name));

                   // close the file
                   fclose($file);

                   // now we encode it and split it into acceptable length lines
                   $data = chunk_split(base64_encode($data));
                }

                // now we'll insert a boundary to indicate we're starting the attachment
                // we have to specify the content type, file name, and disposition as
                // an attachment, then add the file content.
                // NOTE: we don't set another boundary to indicate that the end of the
                // file has been reached here. we only want one boundary between each file
                // we'll add the final one after the loop finishes.
                $message .= "--{$mime_boundary}\n" .
                   "Content-Type: {$type};\n" .
                   " name=\"{$name}\"\n" .
                   "Content-Disposition: attachment;\n" .
                   " filename=\"{$fileatt_name}\"\n" .
                   "Content-Transfer-Encoding: base64\n\n" .
                $data . "\n\n";
             }
          }


$ok = @mail($to, $subject, $message , $headers);
if ($ok) {
if (($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/pjpeg")
&& ($_FILES["file"]["size"] < 20000))
  {
  if ($_FILES["file"]["error"] > 0)
    {
    echo "Return Code: " . $_FILES["file"]["error"] . "<br />";
    }
  else
    {

if (file_exists("upload/" . $_FILES["file"]["name"]))
      {
      echo $_FILES["file"]["name"] . " already exists. ";
      }
    else
      {
      move_uploaded_file($_FILES["file"]["tmp_name"],
      "upload/" . $_FILES["file"]["name"]);

      }
    }
  }
else
  {

  }
echo "<span class='red'>E-mail has been sent successfully from $mail_name to $to</span>"; }
else{
echo "<span class='red'>Failed to send the E-mail from $from to $to</span>";
}
}
?>

p/s:I used this code.hope its work and assist you.just copy and paste.make sure your textfield name is same as in this page.its work for all types of files.for further questions,just email me at [email protected],i also in learning process.=).thanks.

Folliculin answered 15/12, 2008 at 9:6 Comment(1)
-1: The OP isn't asking how to send emails. He wants to retrieve them.Ranchod

© 2022 - 2024 — McMap. All rights reserved.