我送使用PHP郵件功能
我只需要找到該郵件的狀態,無論是交付或退回
郵件有沒有解決這個任何可能的方式未發送郵件ID退回或問題如何找到使用PHP
回答
您可以使用返回路徑頭與特定的電子郵件地址 - 例如[email protected] 之後,所有的反彈(未交付)的電子郵件將返回到收件箱[email protected]
您可以通過PHP連接到此pop3收件箱並閱讀所有消息。 解析每一個消息,並找到(可能是通過正則表達式)錯誤代碼和原因......
我用這個代碼:
$bounce = new BounceMail();
$bounce->setDebug(false);
//create connection
$bounce->createConnection('server', 110, 'user', 'password');
//parse messages
$bounce->parseMessages();
//save parsed messages to database
$messages = $bounce->getParsedMessages();
foreach ($messages as $message_id => $message) {
/* variable $message looks like:
$message = array(
'email_address' => 'email',
'bounce_type' => 'bounce type',
'smtp_server' => 'smtp_server',
'smtp_error' => 'smtp_error',
);
*/
//save returned email to database here
}
和BounceMail類:
<?php
/*
* Depends on 'Net/POP3.php';
*/
/**
* Class BounceMail
*/
class BounceMail extends Net_POP3
{
/**
* @var array
*/
private $messages = array();
/**
* @var array
*/
private $parsed_messages = array();
/**
* @var array
*/
private $partially_parsed_messages = array();
/**
* @var array
*/
private $allowed_email_domains = array();
/**
* @var array
*/
private $allowed_email_addresses = array();
/**
* @param $host
* @param $port
* @param $username
* @param $password
* @return bool
* @throws ErrorException
*/
public function createConnection($host, $port, $username, $password)
{
if (!$this->connect($host, $port)) {
Throw new ErrorException("Error connecting to POP3 socket.");
}
if (true !== ($login = $this->login($username, $password, true))) {
Throw new ErrorException("Login failed:" . $login->getMessage());
}
if (false === ($messages = $this->getListing())) {
Throw new ErrorException("Error getting POP3 box listing.");
} else {
$this->messages = $messages;
}
return true;
}
/**
* @return bool
*/
public function parseMessages()
{
$this->newDebugMessage('PARSING ' . count($this->messages) . ' MESSAGES');
$fully_parsed = 0;
foreach ($this->messages as $message) {
$parsed_message = $this->parseMessage($message);
$email_address = $this->getEmailAddress($parsed_message);
$smtp_error = $this->getSMTPError($parsed_message);
$smtp_server = $this->getSMTPServer($parsed_message);
$bounce_type = $this->getBounceType($smtp_error);
if ($this->checkAllowedContent($parsed_message)) {
$this->newParsedMessage($message['msg_id'], $email_address, $smtp_server, $smtp_error, $bounce_type);
if (!empty($email_address) && !empty($smtp_error) && !empty($smtp_server) && !empty($bounce_type)) {
$fully_parsed++;
} elseif (!empty($email_address) && (empty($smtp_error) || empty($smtp_server) || empty($bounce_type))) {
$this->newPartiallyParsedMessage($email_address, $parsed_message, array($smtp_error, $smtp_server, $bounce_type));
}
}
}
$this->newDebugMessage('SUCCESSFULLY PARSED ' . count($this->parsed_messages) . ' MESSAGES');
$this->newDebugMessage('EVERYTHING FOUND IN ' . $fully_parsed . ' MESSAGES');
return true;
}
/**
* @return array
*/
public function getParsedMessages()
{
return $this->parsed_messages;
}
/**
* @param bool $as_text
* @return array|string
*/
public function getPartiallyParsedMessages($as_text = true)
{
if ($as_text) {
$text = '';
foreach ($this->partially_parsed_messages as $message) {
foreach ($message as $data) {
$text .= $data . "\r\n";
}
$text .= "\r\n---------------\r\n\r\n";
}
return $text;
} else {
return $this->partially_parsed_messages;
}
}
/**
* @param array $domains
*/
public function setAllowedEmailDomains(array $domains)
{
$this->allowed_email_domains = $domains;
}
/**
* @param array $addresses
*/
public function setAllowedEmailAddresses(array $addresses)
{
$this->allowed_email_addresses = $addresses;
}
/**
* @param $message
* @return bool|string
*/
public function newDebugMessage($message)
{
if ($this->_debug) {
$trace = debug_backtrace();
$debug_message = !empty($trace) && isset($trace[1]["function"]) ? $trace[1]["function"] . ' | ' : '';
$debug_message .= !empty($trace) && isset($trace[1]["method"]) ? $trace[1]["method"] . ' | ' : '';
$debug_message .= $message . "\r\n";
echo $debug_message;
return $debug_message;
}
return false;
}
/**
* @param $parsed_message
* @return bool
*/
private function checkAllowedContent($parsed_message)
{
foreach ($parsed_message as $content) {
if (!$this->parseAllowedContent($content)) {
return false;
}
}
return true;
}
/**
* @param $content
* @return bool
*/
private function parseAllowedContent($content)
{
$patterns = array(
'SENDER POLICY FRAMEWORK' => '/(5.7.1\s*Sender\s*Policy\s*Framework)/im',
'TOO MANY HOPS' => '/too\s*many\s*hops/im',
'BLOCKED' => '/554\s*Blocked\s*by\s*Reputation\s*Enabled\s*Defense/im'
);
foreach ($patterns as $name => $pattern) {
$matches = array();
preg_match($pattern, $content, $matches);
if (isset($matches[1]) && !empty($matches[1])) {
$this->newDebugMessage('DISALLOWED CONTENT FOUND (' . $name . ')');
return false;
}
}
return true;
}
/**
* @param $message_id
* @param $email_address
* @param $smtp_server
* @param $smtp_error
* @param $bounce_type
* @return array|bool
*/
private function newParsedMessage($message_id, $email_address, $smtp_server, $smtp_error, $bounce_type)
{
if (!empty($message_id) && !empty($email_address)) {
return $this->parsed_messages[$message_id] = array('email_address' => $email_address, 'smtp_server' => $smtp_server, 'smtp_error' => $smtp_error, 'bounce_type' => $bounce_type);
}
return false;
}
/**
* @param $email_address
* @param array $parsed_message
* @param array $vars
* @return array|bool
*/
private function newPartiallyParsedMessage($email_address, array $parsed_message, array $vars = array())
{
$full_content = '';
foreach ($parsed_message as $content) {
$full_content .= $content . "\r\n";
}
if (!empty($email_address) && !empty($full_content)) {
if (!empty($vars)) {
foreach ($vars as $var) {
$full_content .= "\r\n" . $var . ' | ';
}
}
return $this->partially_parsed_messages[] = array($email_address, $full_content);
} else {
return false;
}
}
/**
* @param $message
* @return array|bool
*/
private function parseMessage($message)
{
if (empty($message)) {
$this->newDebugMessage('Empty message');
return false;
}
if (!$content = $this->getMsg($message['msg_id'])) {
$this->newDebugMessage('Error reading content of message :' . $message['msg_id'] . '/' . $message['uidl']);
}
//todo add attachments
if (!empty($content)) {
return array('content' => $content);
}
return false;
}
/**
* @param $parsed_message
* @return bool
*/
private function getEmailAddress($parsed_message)
{
if (empty($parsed_message)) {
$this->newDebugMessage('Empty parsed message');
return false;
}
$found_emails = array();
foreach ($parsed_message as $content) {
$found_emails = array_unique(array_merge($found_emails, $this->parseEmailAddress($content)));
}
if (count($found_emails) > 1) {
$this->newDebugMessage('More than one e-mail address found: ' . join('; ', $found_emails));
return false;
}
if (count($found_emails) == 1) {
$this->newDebugMessage('Found e-mail address: ' . $found_emails[0]);
return $found_emails[0];
}
$this->newDebugMessage('No e-mail address found');
return false;
}
/**
* @param $content
* @return array
*/
private function parseEmailAddress($content)
{
$email_patterns = array('/[^-]To:\s?<?([a-zA-Z0-9_.-][email protected][a-zA-Z0-9-]+.[a-zA-Z0-9-.]+)>?/i',);
$found_emails = array();
foreach ($email_patterns as $pattern) {
$matches = array();
preg_match_all($pattern, $content, $matches);
if (!empty($matches) && isset($matches[1])) {
$recipient_emails = $matches[1];
$recipient_emails = array_filter($recipient_emails, array($this, 'filter_allowed_domains'));
$recipient_emails = array_filter($recipient_emails, array($this, 'filter_allowed_addresses'));
if (!empty($recipient_emails)) {
$found_emails = array_unique(array_merge($found_emails, $recipient_emails));
}
}
}
return $found_emails;
}
/**
* @param $email
* @return bool
*/
private function filter_allowed_domains($email)
{
return !in_array(substr(strrchr($email, "@"), 1), $this->allowed_email_domains);
}
/**
* @param $email
* @return bool
*/
private function filter_allowed_addresses($email)
{
return !in_array($email, $this->allowed_email_addresses);
}
/**
* @param $smtp_error
* @return bool|int
*/
private function getBounceType($smtp_error)
{
if (empty($smtp_error)) {
$this->newDebugMessage('Empty smtp error');
return false;
}
$status = substr($smtp_error, 0, 1);
switch ($status) {
case 4:
return 1; //temporary
break;
case 5:
return 2; //permanent
break;
}
return false;
}
/**
* @param $parsed_message
* @return bool
*/
private function getSMTPServer($parsed_message)
{
if (empty($parsed_message)) {
$this->newDebugMessage('Empty parsed message');
return false;
}
$found = array();
foreach ($parsed_message as $content) {
$found = array_unique(array_merge($found, $this->parseSMTPServer($content)));
}
if (count($found) > 0) {
$server = substr(join('; ', $found), 0, 254);
$this->newDebugMessage('Found SMTP server: ' . $server);
return $server;
}
$this->newDebugMessage('No SMTP server found');
return false;
}
/**
* @param $content
* @return array
*/
private function parseSMTPServer($content)
{
$patterns = array('/remote-mta:\s?dns;\s?([^\s]*)/i', '/reporting-mta:\s?dns;\s?([^\s]*)/i', '/received-from-mta:\s?dns;\s?([^\s]*)/i');
$found_statuses = array();
foreach ($patterns as $pattern) {
$matches = array();
preg_match_all($pattern, $content, $matches);
if (!empty($matches) && isset($matches[1])) {
$found_statuses = array_unique(array_merge($found_statuses, $matches[1]));
}
}
return $found_statuses;
}
/**
* @param $parsed_message
* @return bool
*/
private function getSMTPError($parsed_message)
{
if (empty($parsed_message)) {
$this->newDebugMessage('Empty parsed message');
return false;
}
$found = array();
foreach ($parsed_message as $content) {
$found = array_unique(array_merge($found, $this->parseSMTPError($content)));
}
if (count($found) > 0) {
$error = substr(join('; ', $found), 0, 19);
$this->newDebugMessage('Found SMTP Error: ' . $error);
return $error;
}
$this->newDebugMessage('No SMTP Error found');
return false;
}
/**
* @param $content
* @return array
*/
private function parseSMTPError($content)
{
//replace errors with codes
$content = str_replace('User mailbox exceeds allowed size', ' 452 4.1.1 ', $content);
$content = str_replace('user is over quota', ' 452 4.1.1 ', $content);
//find error
$patterns = array(
'/status:\s?#?(\d\.\d\.\d)/i',
'/[\d]{3}\s#?(\d\.\d\.\d)/',
'/\(#(\d\.\d\.\d)\)/',
'/Remote SMTP Server Returned:\s?#?([\d]{3})/i',
);
$found_statuses = array();
foreach ($patterns as $pattern) {
$matches = array();
preg_match_all($pattern, $content, $matches);
if (!empty($matches) && isset($matches[1])) {
$found_statuses = array_unique(array_merge($found_statuses, $matches[1]));
}
}
return $found_statuses;
}
}
你應該增加更多regulars into parseSMTPError
我發送的每封郵件都將存儲在數據庫中
我只需要只有狀態「失敗」或「成功」 –
coolprarun
您必須監控未發送的退回電子郵件。如果您發送電子郵件,您不知道它是否已交付,直到您有(或沒有)返回的電子郵件 – emte
是否有任何腳本直接寫入失敗消息到數據庫,以便我可以查看所有狀態單地方@emte – coolprarun
- 1. 使用array_search()找到PHP
- 2. 如何找到在Php
- 3. 如何找到在PHP
- 4. mysql - php。如何找到
- 5. 如何找到使用VBA
- 6. 如何使用XPath找到
- 7. 如何找到使用EPPlus
- 8. 如何找到使用javascript
- 9. 如何找到使用jQuery
- 10. 如何找到未使用
- 11. 如何找到使用TSQL
- 12. 如何找到使用jQuery
- 13. 如何找到使用WLST
- 14. 如何用php找到windows的版本
- 15. 如何找到使用PHP的公用文件夾?
- 16. 如何使用PHP找到兩種貨幣之間的匯率
- 17. 如何找到使用php的數組中最小的值?
- 18. 如何找到使用PHP的圖像的「多數顏色」?
- 19. 如何找到一類在數據庫中使用ID在PHP
- 20. 如何找到朋友誰是當今使用PHP和MYSQL
- 21. 如何找到使用PHP的圖像寬度?
- 22. 如何在kml文件中使用php找到位置
- 23. PHP:使用ftp_put導致錯誤,如何找到原因?
- 24. 如何使用php在數組中找到重複值?
- 25. 如何找到PHP文件中使用的所有類?
- 26. 如何找到使用php的圖像中心imagemagick
- 27. 如何找到使用PHP的網站的主機?
- 28. 如何在PHP表中找到下一個可用的整數使用PHP
- 29. 使用PHP找到URL的一部分
- 30. 使用php/silex找到「Class not found」
好的,祝你好運。 (即,這看起來更像是一個聲明,如果你不提供詳細信息/帶有特定問題,我們不能幫你) – AmazingDreams