如何从 PHP 获取电子邮件及其附件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/114953/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get email and their attachments from PHP
提问by Oli
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.
我正在为朋友的婚礼编写一个照片库 web 应用程序,他们想要一个照片库供客人提交他们当天拍摄的数码照片。
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?
我已经创建了一个邮箱,但现在我需要连接和检索这些附件以进行自动处理以添加到画廊系统。但是如何?有没有你见过的教程或预制类这样做?
采纳答案by Armin Ronacher
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).
你用的是什么 MTA?如果您使用 postfix + maildrop,您可以创建一个过滤规则,通过 PHP 脚本处理某些邮件,然后处理传入的邮件。(google for maildrop 和xfilter)。
回答by DreamWerx
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. ;(
我以前做过很多这样的事情,但我找不到代码,这是我找到的缩小版本。它应该让你走上正确的道路。我曾经从 cronjob 运行这种类型的脚本。抱歉,我找不到最终版本。;(
// 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!
祝你好运!
回答by Daniel Papasian
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.
如果您为此目的创建专用邮箱,那么使用过滤机制几乎绝对不是您想要的。相反,您希望邮箱成为应用程序的管道,让应用程序简单地从标准输入读取消息,解析正文,然后 MIME 解析正文以获取附件。
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:
我所知道的所有流行的基于 unix 的 MTA 都支持将邮箱作为管道,例如 sendmail、postfix 和 qmail。通常,您在别名文件中定义它,如下所示:
# sendmail or postfix syntax
msgsubmit: "| /usr/bin/php ~path/to/example.php"
# sendmail 或 postfix 语法
msgsubmit: "| /usr/bin/php ~path/to/example.php"
Then mails to msgsubmit@ get routed to a php program for delivery.
然后发送到 msgsubmit@ 的邮件被路由到一个 php 程序进行传送。
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.
这样做的优点是不依赖于 IMAP 服务器或 MTA 之外的任何其他处于活动状态的服务器,并且只要您可以控制目标主机的 MTA,它就可以正常工作。如果您希望脚本检查系统上的所有消息,那么过滤就是您想要的,我猜不是这种情况。
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
回答by Liam
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.
您是否考虑过使用 Google 的Picasa 网络相册?您可以设置电子邮件地址以将照片发送到并在线共享。然后,您可以获得这些照片的 RSS 提要,大多数程序员比 MTA 更熟悉这种提要。
回答by Armin Ronacher
I think you want a MIME message parser.
我想你想要一个 MIME 消息解析器。
I've used this onebefore 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).
我以前用过这个,它似乎工作得很好,虽然我没有在非常大的附件上测试过它(即你可能从数码相机获得的 2-3MB 文件)。
Have you already got a system for reading POP3 / IMAP mailboxes? There is another classon 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.
您是否已经拥有读取 POP3 / IMAP 邮箱的系统?同一站点上还有另一个类也适用于 POP3(我相信还有一个 IMAP 类)-但是,如果您要下载相当数量的内容,也许您会想要研究一些基于 C 的解决方案,因为我相信一种是纯PHP。
回答by paulo lellis
Majordomo, could be an alternative to handle emails, but there are some limitations on file attachment handling.
Majordomo, 可能是处理电子邮件的替代方法,但在文件附件处理方面存在一些限制。
回答by paulo lellis
<?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.
p/s:我使用了这个代码。希望它的工作能帮助你。只需复制和粘贴。确保你的文本字段名称与此页面中的名称相同。它适用于所有类型的文件。如有进一步问题,请给我发电子邮件 shah @mc-oren.com.anyway,我也在学习过程中。=)。谢谢。

