library - phpmailer example
analizar el correo electrónico sin procesar en php (14)
Estoy buscando un código php bueno / funcional / fácil de usar para analizar el correo electrónico sin procesar en partes.
He escrito un par de soluciones de fuerza bruta, pero cada vez aparece un pequeño cambio / encabezado / espacio / algo y todo mi analizador falla y el proyecto se desmorona.
Y antes de que me señalen PEAR / PECL, necesito el código real. Mi anfitrión tiene algunas configuraciones confusas o algo así, parece que nunca puedo obtener el .so''s para compilar correctamente. Si obtengo el .so, alguna diferencia en path / environment / php.ini no siempre está disponible (apache vs cron vs cli).
Ah, y una última cosa, estoy analizando el texto del correo electrónico sin procesar, NO POP3, y NO IMAP. Está siendo canalizado en la secuencia de comandos php a través de un redireccionamiento de correo electrónico .qmail.
No espero que SOF lo escriba para mí, estoy buscando algunos consejos / puntos de partida para hacerlo "bien". Este es uno de esos problemas de "rueda" que sé que ya se resolvió.
¿Con qué esperas terminar al final? El cuerpo, el sujeto, el remitente, un archivo adjunto? Debería pasar un tiempo con RFC2822 para comprender el formato del correo, pero estas son las reglas más simples para un correo electrónico bien formado:
HEADERS/n
/n
BODY
Es decir, la primera línea en blanco (doble línea nueva) es el separador entre los ENCABEZADOS y el CUERPO. UNA CABEZA se ve así:
HSTRING:HTEXT
HSTRING siempre comienza al comienzo de una línea y no contiene ningún espacio en blanco o dos puntos. HTEXT puede contener una amplia variedad de texto, incluidas líneas nuevas, siempre que la nueva línea sea seguida por espacios en blanco.
El "CUERPO" es realmente cualquier dato que sigue a la primera doble línea nueva. (Hay reglas diferentes si está transmitiendo correo a través de SMTP, pero si lo procesa en una tubería, no tiene que preocuparse por eso).
Entonces, en términos RFC822 realmente simples, circa-1982, un correo electrónico se ve así:
HEADER: HEADER TEXT
HEADER: MORE HEADER TEXT
INCLUDING A LINE CONTINUATION
HEADER: LAST HEADER
THIS IS ANY
ARBITRARY DATA
(FOR THE MOST PART)
Sin embargo, la mayoría del correo electrónico moderno es más complejo que eso. Los encabezados pueden codificarse para RFC2047 o palabras de mimo RFC2047 , o un montón de otras cosas en las que no estoy pensando en este momento. Los cuerpos son realmente difíciles de rodar tu propio código en estos días si quieres que sean significativos. Casi todos los correos electrónicos generados por un MUA tendrán codificación MIME . Eso podría ser un texto cifrado, podría ser html, podría ser una hoja de cálculo excel de uuencoded.
Espero que esto ayude a proporcionar un marco para entender algunos de los contenedores de correo electrónico más elementales. Si proporciona más información sobre lo que intenta hacer con los datos, yo (u otra persona) podría proporcionar una mejor dirección.
Arreglé esto, un código no es mío, pero no sé de dónde vino ... Más tarde adopté el más robusto "MimeMailParser", pero funciona bien, canalizo mi correo electrónico predeterminado usando cPanel y funciona estupendo.
#!/usr/bin/php -q
<?php
// Config
$dbuser = ''emlusr'';
$dbpass = ''pass'';
$dbname = ''email'';
$dbhost = ''localhost'';
$notify= ''[email protected]''; // an email address required in case of errors
function mailRead($iKlimit = "")
{
// Purpose:
// Reads piped mail from STDIN
//
// Arguements:
// $iKlimit (integer, optional): specifies after how many kilobytes reading of mail should stop
// Defaults to 1024k if no value is specified
// A value of -1 will cause reading to continue until the entire message has been read
//
// Return value:
// A string containing the entire email, headers, body and all.
// Variable perparation
// Set default limit of 1024k if no limit has been specified
if ($iKlimit == "") {
$iKlimit = 1024;
}
// Error strings
$sErrorSTDINFail = "Error - failed to read mail from STDIN!";
// Attempt to connect to STDIN
$fp = fopen("php://stdin", "r");
// Failed to connect to STDIN? (shouldn''t really happen)
if (!$fp) {
echo $sErrorSTDINFail;
exit();
}
// Create empty string for storing message
$sEmail = "";
// Read message up until limit (if any)
if ($iKlimit == -1) {
while (!feof($fp)) {
$sEmail .= fread($fp, 1024);
}
} else {
while (!feof($fp) && $i_limit < $iKlimit) {
$sEmail .= fread($fp, 1024);
$i_limit++;
}
}
// Close connection to STDIN
fclose($fp);
// Return message
return $sEmail;
}
$email = mailRead();
// handle email
$lines = explode("/n", $email);
// empty vars
$from = "";
$subject = "";
$headers = "";
$message = "";
$splittingheaders = true;
for ($i=0; $i < count($lines); $i++) {
if ($splittingheaders) {
// this is a header
$headers .= $lines[$i]."/n";
// look out for special headers
if (preg_match("/^Subject: (.*)/", $lines[$i], $matches)) {
$subject = $matches[1];
}
if (preg_match("/^From: (.*)/", $lines[$i], $matches)) {
$from = $matches[1];
}
if (preg_match("/^To: (.*)/", $lines[$i], $matches)) {
$to = $matches[1];
}
} else {
// not a header, but message
$message .= $lines[$i]."/n";
}
if (trim($lines[$i])=="") {
// empty line, header section has ended
$splittingheaders = false;
}
}
if ($conn = @mysql_connect($dbhost,$dbuser,$dbpass)) {
if(!@mysql_select_db($dbname,$conn))
mail($email,''Email Logger Error'',"There was an error selecting the email logger database./n/n".mysql_error());
$from = mysql_real_escape_string($from);
$to = mysql_real_escape_string($to);
$subject = mysql_real_escape_string($subject);
$headers = mysql_real_escape_string($headers);
$message = mysql_real_escape_string($message);
$email = mysql_real_escape_string($email);
$result = @mysql_query("INSERT INTO email_log (`to`,`from`,`subject`,`headers`,`message`,`source`) VALUES(''$to'',''$from'',''$subject'',''$headers'',''$message'',''$email'')");
if (mysql_affected_rows() == 0)
mail($notify,''Email Logger Error'',"There was an error inserting into the email logger database./n/n".mysql_error());
} else {
mail($notify,''Email Logger Error'',"There was an error connecting the email logger database./n/n".mysql_error());
}
?>
El Pear lib Mail_mimeDecode está escrito en PHP simple que puedes ver aquí: Mail_mimeDecode source
El análisis de correo electrónico en PHP no es una tarea imposible. Lo que quiero decir es que no necesitas un equipo de ingenieros para hacerlo; es alcanzable como un individuo. Realmente la parte más difícil que encontré fue crear el FSM para analizar un resultado IMAP BODYSTRUCTURE. En ninguna parte de Internet había visto esto, así que escribí el mío. Mi rutina básicamente crea una matriz de matrices anidadas desde la salida del comando, y la profundidad en la que se encuentra la matriz corresponde aproximadamente a los números de parte necesarios para realizar las búsquedas. Por lo tanto, maneja las estructuras MIME anidadas con bastante gracia.
El problema es que las funciones predeterminadas imap_ * de PHP no proporcionan mucha granularidad ... así que tuve que abrir un socket al puerto IMAP y escribir las funciones para enviar y recuperar la información necesaria (IMAP FETCH 1 BODY.PEEK [1.2] por ejemplo), y eso implica mirar la documentación de RFC.
La codificación de los datos (quoted-printable, base64, 7bit, 8bit, etc.), la longitud del mensaje, el tipo de contenido, etc., se le proporciona a usted; para archivos adjuntos, texto, html, etc. Puede que tenga que descubrir los matices de su servidor de correo también, ya que no todos los campos están siempre implementados al 100%.
La gema es el FSM ... si tienes experiencia en Comp Sci, puede ser muy divertido hacer esto (la clave es que los paréntesis no son una gramática regular;)); de lo contrario, será una lucha y / o dará como resultado un código feo, utilizando métodos tradicionales. ¡También necesitas algo de tiempo!
¡Espero que esto ayude!
Esta biblioteca funciona muy bien:
http://www.phpclasses.org/package/3169-PHP-Decode-MIME-e-mail-messages.html
Este https://github.com/zbateson/MailMimeParser funciona para mí y no necesita extensión mailparse.
<?php
echo $message->getHeaderValue(''from''); // [email protected]
echo $message
->getHeader(''from'')
->getPersonName(); // Person Name
echo $message->getHeaderValue(''subject''); // The email''s subject
echo $message->getTextContent(); // or getHtmlContent
Hay funciones de Mailparse que puedes probar: http://php.net/manual/en/book.mailparse.php , no en php conf predeterminado, sin embargo.
Hay una biblioteca para analizar el mensaje de correo electrónico sin procesar en la matriz php - http://flourishlib.com/api/fMailbox#parseMessage .
El método estático parseMessage () se puede utilizar para analizar un mensaje de correo electrónico MIME completo en el mismo formato que fetchMessage () devuelve, menos la clave uid.
$ parsed_message = fMailbox :: parseMessage (file_get_contents (''/ path / to / email''));
Aquí hay un ejemplo de un mensaje analizado:
array(
''received'' => ''28 Apr 2010 22:00:38 -0400'',
''headers'' => array(
''received'' => array(
0 => ''(qmail 25838 invoked from network); 28 Apr 2010 22:00:38 -0400'',
1 => ''from example.com (HELO ?192.168.10.2?) (example) by example.com with (DHE-RSA-AES256-SHA encrypted) SMTP; 28 Apr 2010 22:00:38 -0400''
),
''message-id'' => ''<[email protected]>'',
''date'' => ''Wed, 28 Apr 2010 21:59:49 -0400'',
''from'' => array(
''personal'' => ''Will Bond'',
''mailbox'' => ''tests'',
''host'' => ''flourishlib.com''
),
''user-agent'' => ''Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.9) Gecko/20100317 Thunderbird/3.0.4'',
''mime-version'' => ''1.0'',
''to'' => array(
0 => array(
''mailbox'' => ''tests'',
''host'' => ''flourishlib.com''
)
),
''subject'' => ''This message is encrypted''
),
''text'' => ''This message is encrypted'',
''decrypted'' => TRUE,
''uid'' => 15
);
Me encontré con el mismo problema, así que escribí la siguiente clase: Email_Parser. Toma un correo electrónico sin formato y lo convierte en un objeto agradable.
Requiere PEAR Mail_mimeDecode, pero debe ser fácil de instalar a través de WHM o directamente desde la línea de comandos.
Obténgalo aquí: https://github.com/optimumweb/php-email-reader-parser
No estoy seguro si esto será de ayuda para usted, eso espero, pero seguramente ayudará a otros interesados en obtener más información sobre el correo electrónico. Marcus Bointon hizo una de las mejores presentaciones tituladas "Mail () y life after Mail ()" en la conferencia PHP London en marzo de este año y las slides y el MP3 están en línea. Habla con cierta autoridad, ya que trabajó extensamente con correo electrónico y PHP a un nivel profundo.
Mi percepción es que te espera un mundo de dolor tratando de escribir un analizador verdaderamente genérico.
EDITAR - Parece que los archivos han sido eliminados en el sitio de PHP London; encontró las diapositivas en el propio sitio de Marcus: Parte 1 Parte 2 No podía ver el MP3 en ninguna parte, aunque
Probablemente no se va a divertir mucho escribiendo su propio analizador MIME. La razón por la que está encontrando "paquetes de manejo de correo sobredesarrollado" es porque MIME es un conjunto realmente complejo de reglas / formatos / codificaciones. Las partes MIME pueden ser recursivas, lo cual es parte de la diversión. Creo que lo mejor es escribir el mejor controlador MIME posible, analizar un mensaje, descartar todo lo que no sea text / plain o text / html, y luego forzar el comando en la cadena entrante que debe tener el prefijo COMMAND: o algo similar para que pueda encontrarlo en el lodo. Si comienzas con reglas como esa, tienes una buena posibilidad de manejar nuevos proveedores, pero deberías estar listo para modificar si aparece un nuevo proveedor (o diablos, si tu proveedor actual elige cambiar su arquitectura de mensajería).
Pruebe el analizador de correo electrónico Plancake PHP: https://github.com/plancake/official-library-php-email-parser
Lo he usado para mis proyectos. Funciona muy bien, es solo una clase y es de código abierto.
Simple PhpMimeParser https://github.com/breakermind/PhpMimeParser Yuo puede cortar mensajes de mime de archivos, cadena. Obtenga archivos, html e imágenes en línea.
$str = file_get_contents(''mime-mixed-related-alternative.eml'');
// MimeParser
$m = new PhpMimeParser($str);
// Emails
print_r($m->mTo);
print_r($m->mFrom);
// Message
echo $m->mSubject;
echo $m->mHtml;
echo $m->mText;
// Attachments and inline images
print_r($m->mFiles);
print_r($m->mInlineList);
sí, he podido escribir un analizador básico, basado en ese rfc y algunos otros tutoriales básicos. pero son los mitades anidados en múltiples partes los que continúan arruinándome.
descubrí que los mensajes MMS (no SMS) enviados desde mi teléfono son solo correos electrónicos estándar, por lo que tengo un sistema que lee el correo electrónico entrante, verifica el (para permitir solo desde mi teléfono) y usa la parte del cuerpo para ejecutar diferentes comandos en mi servidor es como un control remoto por correo electrónico.
porque el sistema está diseñado para enviar imágenes, tiene un montón de partes codificadas de forma diferente. una parte mms.smil.txt, un texto / plano (que es inútil, simplemente dice ''este es un mensaje html''), una parte de la aplicación / smil (que la parte que los teléfonos verían), una parte text / html con un anuncio de mi operador, luego mi mensaje, pero todo envuelto en html, y finalmente un archivo de texto adjunto con mi mensaje simple (que es la parte que uso) (si inserto una imagen como archivo adjunto en el mensaje, se pone en archivo adjunto 1, codificado en base64, luego mi porción de texto se adjunta como archivo adjunto 2)
Lo tuve trabajando con el formato de correo exacto de mi proveedor, pero cuando lo transmití desde el teléfono de otra persona, falló de muchas maneras miserables.
Tengo otros proyectos en los que me gustaría extender este sistema de comando de teléfono-> correo-> parse->, pero necesito tener un analizador estable / sólido / genérico para obtener las diferentes partes del correo para usarlo.
mi objetivo final sería tener una función en la que pudiera alimentar el correo sin procesar, y obtener una gran matriz con sub-matrices asociativas de pares de encabezados var: val y una para el texto del cuerpo como una cadena completa
cuanto más busco en esto, más encuentro lo mismo: paquetes de manejo de correo gigante sobredesarrollado que hacen todo lo que está bajo el sol relacionado con correos electrónicos, o tutoriales inútiles (para mí, en este proyecto).
Creo que voy a tener que morder la bala y solo escribir algo mío.