php

2008-08-15 7 views
24

में कच्चे ईमेल को पार्स करना मैं भागों में कच्चे ईमेल को पार्स करने के लिए PHP कोड का उपयोग करने के लिए अच्छा/काम करने वाला/सरल ढूंढ रहा हूं।php

मैं जानवर बल समाधान के एक जोड़े में लिखा है, लेकिन हर बार, एक छोटा सा परिवर्तन/हैडर/अंतरिक्ष/कुछ साथ आता है और मेरी पूरी पार्सर विफल रहता है और परियोजना के अलावा गिर जाता है।

और इससे पहले कि मैं पीएआर/पीईसीएल पर इंगित करता हूं, मुझे वास्तविक कोड की आवश्यकता है। मेरे मेजबान में कुछ खराब कॉन्फ़िगरेशन या कुछ है, मैं कभी भी सही बनाने के लिए .so को प्राप्त नहीं कर सकता। अगर मुझे एसएसओ बनाया जाता है, तो पथ/पर्यावरण/php.ini में कुछ अंतर हमेशा इसे उपलब्ध नहीं करता है (अपाचे बनाम क्रॉन बनाम क्ली)।

ओह, और एक आखिरी बात, मैं कच्चे ईमेल पाठ, पॉप 3 नहीं, और नहीं IMAP को पार्स कर रहा हूँ। इसे एक .qmail ईमेल रीडायरेक्ट के माध्यम से php स्क्रिप्ट में पाइप किया जा रहा है।

मैं SOF उम्मीद नहीं कर रहा हूँ मेरे लिए यह लिखने के लिए, मैं यह कर "सही" पर कुछ सुझाव/प्रारंभिक बिंदु की तलाश में हूँ। यह उन "पहिया" समस्याओं में से एक है जो मुझे पता है कि पहले ही हल हो चुका है।

उत्तर

19

आप अंत में अंत तक क्या उम्मीद कर रहे हैं? शरीर, विषय, प्रेषक, एक लगाव? आप मेल के प्रारूप को समझने के लिए RFC2822 साथ कुछ समय बिताना चाहिए, लेकिन यहाँ अच्छी तरह का गठन ईमेल के लिए सबसे सरल नियम है:

HEADERS\n 
\n 
BODY 

यही है, पहले रिक्त पंक्ति (डबल newline) हेडर और के बीच विभाजक है शरीर। एक हैडर इस तरह दिखता है:

HSTRING:HTEXT 

HSTRING हमेशा एक पंक्ति के आरंभ में शुरू होता है और किसी भी सफेद स्थान या कोलन शामिल नहीं है। HTEXT में कई प्रकार के टेक्स्ट हो सकते हैं, जिनमें न्यूलाइन शामिल हैं, जब तक कि न्यूलाइन चार के बाद व्हाइटस्पेस हो।

"द बॉडी" वास्तव में सिर्फ किसी भी डेटा को पहला दोहरा न्यू लाइन इस प्रकार है। (यदि आप एसएमटीपी के माध्यम से मेल प्रेषित कर रहे हैं तो विभिन्न नियम हैं, लेकिन इसे एक पाइप पर संसाधित करना आपको इसके बारे में चिंता करने की ज़रूरत नहीं है)।

तो, वास्तव में सरल, लगभग -1982 RFC822 मामले में, एक ईमेल इस तरह दिखता है:

HEADER: HEADER TEXT 
HEADER: MORE HEADER TEXT 
    INCLUDING A LINE CONTINUATION 
HEADER: LAST HEADER 

THIS IS ANY 
ARBITRARY DATA 
(FOR THE MOST PART) 

अधिकांश आधुनिक ईमेल हालांकि उससे कहीं अधिक जटिल है। हेडर को वर्णमाला या RFC2047 माइम शब्द, या अन्य सामानों का एक टन के लिए एन्कोड किया जा सकता है, जिसे मैं अभी नहीं सोच रहा हूं। यदि आप चाहते हैं कि वे सार्थक हों तो शरीर इन दिनों के लिए अपना कोड रोल करना वाकई मुश्किल है। एमयूए द्वारा उत्पन्न लगभग सभी ईमेल MIME एन्कोडेड होंगे। यह यूनकोडेड टेक्स्ट हो सकता है, यह एचटीएमएल हो सकता है, यह एक यूएनकोडेड एक्सेल स्प्रैडशीट हो सकता है।

मैं इस आशा ईमेल के बहुत मौलिक बाल्टी के कुछ समझने के लिए एक रूपरेखा प्रदान में मदद करता है। यदि आप डेटा (या किसी और) के साथ क्या करने का प्रयास कर रहे हैं, तो आप अधिक दिशा प्रदान कर सकते हैं, तो बेहतर दिशा प्रदान करने में सक्षम हो सकता है।

0

हाँ, कि आरएफसी और कुछ अन्य बुनियादी ट्यूटोरियल पर आधारित एक बुनियादी पार्सर लिखने में सक्षम किया गया ive,। लेकिन इसके मल्टीपार्ट माइम ने सीमाएं निहित की हैं जो मुझे गड़बड़ कर रही हैं।

मैं पता चला कि एमएमएस (नहीं एसएमएस) मेरे फोन से भेजे गए संदेशों सिर्फ मानक ईमेल कर रहे हैं, तो मैं एक प्रणाली है कि आने वाली ईमेल पढ़ता है, की जाँच करता है से (केवल करने के लिए अपने फोन से अनुमति देते हैं), और शरीर का उपयोग करता है मेरे सर्वर पर अलग-अलग कमांड चलाने के लिए भाग। ईमेल द्वारा रिमोट कंट्रोल की तरह इसकी तरह।

क्योंकि इस प्रणाली चित्रों को भेजने के लिए बनाया गया है, अपनी अलग एन्कोड भागों का एक गुच्छा मिला है। एक mms.smil.txt भाग, एक पाठ/सादा (जो बेकार है, बस कहता है 'यह एक HTML संदेश है'), एक आवेदन/मुस्कुराहट हिस्सा (जिस भाग पर फोन पिक होगा), एक पाठ/एचटीएमएल भाग मेरे वाहक के लिए एक विज्ञापन के साथ, फिर मेरा संदेश, लेकिन सभी एचटीएमएल में लिपटे, फिर आखिरकार मेरे सादे संदेश (जो मैं हिस्सा का उपयोग करता हूं) के साथ एक टेक्स्टफाइल अटैचमेंट (अगर मैं एक छवि को संदेश में अनुलग्नक के रूप में ढकता हूं, तो इसे डाल दिया जाता है अनुलग्नक 1, बेस 64 एन्कोडेड, फिर मेरा टेक्स्ट भाग संलग्नक के रूप में संलग्न है 2)

मैंने इसे अपने वाहक से सटीक मेल प्रारूप के साथ काम किया था, लेकिन जब मैंने किसी के माध्यम से किसी अन्य फोन से संदेश चलाया, तो यह विफल रहा दुखी तरीके से पूरा गुच्छा।

मेरे पास अन्य परियोजनाएं हैं जो मैं इस फोन-> मेल-> पार्स-> कमांड सिस्टम को विस्तारित करना चाहता हूं, लेकिन मुझे मेल से अलग हिस्सों को प्राप्त करने के लिए एक स्थिर/ठोस/जेनेरिक पार्सर होना चाहिए इसका इस्तेमाल करें।

मेरा अंतिम लक्ष्य एक ऐसा कार्य होगा जिसमें मैं कच्चे पाइप वाले मेल को खिला सकता हूं, और शीर्षकों के सहयोगी उप-सरणी के साथ एक बड़ी सरणी वापस प्राप्त कर सकता हूं: वैल जोड़े, और शरीर के पाठ के लिए एक स्ट्रिंग

जितना अधिक मैं इस पर खोज करता हूं, उतना ही मुझे एक ही चीज़ मिलती है: विशाल अतिरंजित मेल हैंडलिंग पैकेज जो मेल से संबंधित सूरज के नीचे सबकुछ करते हैं, या बेकार (मेरे लिए, इस परियोजना में) ट्यूटोरियल।

मैं मैं गोली काटने और बस ध्यान से कुछ मेरी स्वयं लिखने के लिए जा रहा हूँ लगता है।

1

आप शायद बहुत ज्यादा नहीं मज़ा अपनी खुद की माइम पार्सर लेखन करने जा रहे हैं। "अविकसित मेल हैंडलिंग पैकेज" ढूंढने का कारण यह है कि एमआईएम नियम/प्रारूप/एन्कोडिंग का एक जटिल सेट है। एमआईएमई भाग रिकर्सिव हो सकते हैं, जो मजेदार का हिस्सा है। मुझे लगता है कि आपका सबसे अच्छा शर्त है कि आप सबसे अच्छा एमआईएम हैंडलर लिख सकते हैं, एक संदेश पार्स कर सकते हैं, टेक्स्ट/सादा या टेक्स्ट/एचटीएमएल नहीं कर सकते हैं, और फिर आने वाली स्ट्रिंग में कमांड को कमांड के साथ प्रीफिक्स्ड करने के लिए मजबूर करें: या कुछ समान ताकि आप इसे मक में पा सकें। यदि आप इस तरह के नियमों से शुरू करते हैं कि आपके पास नए प्रदाताओं को संभालने का एक अच्छा मौका है, लेकिन यदि कोई नया प्रदाता साथ आता है (या हेक, यदि आपका वर्तमान प्रदाता अपने संदेश आर्किटेक्चर को बदलना चुनता है) तो आपको ट्विक करने के लिए तैयार रहना चाहिए। इसलिए उम्मीद है कि - - लेकिन यह निश्चित रूप से ईमेल के बारे में अधिक जानने में रुचि रखते दूसरों की मदद करेगा

1

मुझे यकीन है कि अगर यह आप के लिए मदद की हो जाएगा नहीं कर रहा हूँ। Marcus Bointon इस वर्ष मार्च में पीएचपी लंदन सम्मेलन में "मेल() के बाद मेल() और जीवन" हकदार सबसे अच्छा प्रस्तुतियों में से एक था और slides और MP3 ऑनलाइन कर रहे हैं। वह कुछ अधिकार के साथ बोलता है, जिसने गहरे स्तर पर ईमेल और PHP के साथ बड़े पैमाने पर काम किया है।

मेरी धारणा यह है कि आप वास्तव में जेनेरिक पार्सर लिखने की कोशिश कर रहे दर्द की दुनिया में हैं।

संपादित करें - फ़ाइलें पीएचपी लंदन साइट पर हटा दिया गया है पसंद करते हैं; मार्कस own site पर स्लाइड पाया: Part 1Part 2 एमपी 3 नहीं देखी जा सकी कहीं भी हालांकि

1

PHP में पार्सिंग ईमेल असंभव कार्य नहीं है। मेरा मतलब है, आपको इंजीनियरों की एक टीम की आवश्यकता नहीं है; यह एक व्यक्ति के रूप में प्राप्य है। वास्तव में मुझे लगता है कि सबसे कठिन हिस्सा एक IMAP बॉडीस्ट्रक्चर परिणाम पार्स करने के लिए एफएसएम बना रहा था। इंटरनेट पर कहीं भी मैंने इसे देखा नहीं था इसलिए मैंने अपना खुद लिखा।मेरा दिनचर्या मूल रूप से कमांड आउटपुट से नेस्टेड सरणी की एक सरणी बनाता है, और सरणी में गहराई वाला गहराई लुकअप करने के लिए आवश्यक भाग संख्या (ओं) से मेल खाती है। तो यह नेस्टेड एमआईएम संरचनाओं को काफी सुंदर तरीके से संभालता है।

समस्या यह है कि PHP के डिफ़ॉल्ट imap_ * फ़ंक्शंस बहुत अधिक मात्रा प्रदान नहीं करते हैं ... इसलिए मुझे IMAP पोर्ट को सॉकेट खोलना था और आवश्यक जानकारी भेजने और पुनर्प्राप्त करने के लिए फ़ंक्शन लिखना था (IMAP FETCH 1 बॉडी। पीईके [1.2] उदाहरण के लिए), और इसमें आरएफसी दस्तावेज को देखना शामिल है।

डेटा का एन्कोडिंग (उद्धृत-प्रिंट करने योग्य, बेस 64, 7 बिट, 8 बिट, आदि), संदेश की लंबाई, सामग्री-प्रकार इत्यादि आपको प्रदान की जाती है; अनुलग्नक, टेक्स्ट, एचटीएमएल इत्यादि के लिए आपको अपने मेल सर्वर की बारीकियों को भी समझना पड़ सकता है क्योंकि सभी फ़ील्ड हमेशा 100% लागू नहीं होते हैं।

मणि एफएसएम है ... यदि आपके पास कॉम्प साइंस में पृष्ठभूमि है तो यह वास्तव में वास्तव में मजेदार हो सकता है (वे कुंजी यह है कि ब्रैकेट नियमित व्याकरण नहीं होते हैं;)); अन्यथा पारंपरिक तरीकों का उपयोग करके यह एक संघर्ष और/या बदसूरत कोड में परिणाम होगा। आपको कुछ समय चाहिए!

आशा है कि इससे मदद मिलती है!

4

मैंने इसे एक साथ जोड़ दिया, कुछ कोड मेरा नहीं है, लेकिन मुझे नहीं पता कि यह कहां से आया था ... मैंने बाद में अधिक मजबूत "माइममेल पार्सर" अपनाया लेकिन यह ठीक काम करता है, मैं इसे अपने डिफ़ॉल्ट ईमेल को पाइप करता हूं सीपीनल और यह बहुत अच्छा काम करता है। https://github.com/plancake/official-library-php-email-parser

मैं अपनी परियोजनाओं के लिए इसका इस्तेमाल किया:

#!/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([email protected]_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()); 
} 
?> 
+0

मुझे यह दृष्टिकोण पसंद है, और यह अधिकांश भाग के लिए काफी अच्छा काम करता है। हालांकि मैंने समस्या निवारण में देखा है कि यह रैपिंग हेडर लाइनों को संभाल नहीं पाएगा, उदाहरण के लिए यदि: पते एक से अधिक पंक्ति का उपयोग करते हैं। –

17

Plancake पीएचपी ईमेल पार्सर का प्रयास करें। यह बहुत अच्छा काम करता है, यह सिर्फ एक वर्ग है और यह खुला स्रोत है।

+0

महान पुस्तकालय दान! आप = 23 और = 40 प्रकार के पात्रों से कैसे छुटकारा पा सकते हैं? – cwd

+0

@cwd जो मुझे लगता है कि टेक्स्ट एन्कोडिंग उद्धृत किया गया है। –

+2

मैं इस lib का उपयोग कर रहा हूं और यह 90% बार काम करता है, लेकिन 100% नहीं ... – behz4d

2

नाशपाती lib Mail_mimeDecode सादे पीएचपी कि आप यहाँ देख सकते हैं में लिखा है: Mail_mimeDecode source

+0

लिंक होना चाहिए http://svn.php.net/viewvc/pear/packages/Mail_mimeDecode/trunk/Mail/mimeDecode.php?revision=337165&view=markup – chiliNUT

+0

btw यह लाइब्रेरी उत्कृष्ट है – chiliNUT

0

यह पुस्तकालय बहुत अच्छी तरह से काम करते हैं:

http://www.phpclasses.org/package/3169-PHP-Decode-MIME-e-mail-messages.html

+0

-1 आपको पंजीकरण करने की आवश्यकता है उस साइट को पाने के लिए, तो दस्तावेज स्पष्ट नहीं है। क्या आप कम से कम इसका उपयोग करने का उदाहरण दे सकते हैं? Plancake जवाब इस से बेहतर दिखता है। – cwd

2

php में कच्चे ई-मेल संदेश पार्स करने के लिए एक पुस्तकालय है सरणी - http://flourishlib.com/api/fMailbox#parseMessage

स्थिर विधि parseMessage() कि fetchMessage() रिटर्न एक ही प्रारूप में एक पूर्ण माइम ई-मेल संदेश को पार्स करने uid कुंजी इस्तेमाल किया जा सकता, शून्य से।

$ parsed_message = fmailbox :: parseMessage (file_get_contents ('/ path/to/email'));

यहाँ एक पार्स संदेश का एक उदाहरण है:

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 
); 
+0

एक आकर्षण की तरह काम करता है! 8-) –

0

मैं एक ही समस्या से मुलाकात की तो मैं निम्नलिखित वर्ग ने लिखा है: Email_Parser। यह एक कच्चा ईमेल लेता है और इसे एक अच्छी वस्तु में बदल देता है।

इसे पियर Mail_mimeDecode की आवश्यकता है लेकिन यह डब्ल्यूएचएम या सीधे कमांड लाइन से स्थापित करना आसान होना चाहिए।

इसे यहाँ प्राप्त करें: https://github.com/optimumweb/php-email-reader-parser

2

मेरे लिए यह https://github.com/zbateson/MailMimeParser काम करता है, और 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 
0

सरल PhpMimeParser https://github.com/breakermind/PhpMimeParser yuo, फाइलों से माइम संदेशों कटौती कर सकते हैं स्ट्रिंग। फ़ाइलें, एचटीएमएल और इनलाइन छवियां प्राप्त करें।

$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); 
संबंधित मुद्दे

 संबंधित मुद्दे