mail_body zerlegen

rernanded

Erfahrenes Mitglied
Hi,
wie kann ich die Ausgabe von Text/Plain aus dem mail_body filtern?
Und wie kann ich das für den Text/HTML machen?
Vllt gehts mit imap_fetchstructure() und / oder imap_fetchbody()? Nur wie?

Moni

PHP:
<?php

$mailbox=imap_open("{MAILSERVER}INBOX","USER","PASSWORD"); 
 

if ($mailbox) 
{ 

$check=imap_check($mailbox); 

$count_msg=$check->Nmsgs; 

$count_new_msg=$check->Recent; 

for ($i=1; $i<=imap_num_msg($mailbox); 
$i++) 
 
{ 
 
$mail_body = imap_body($mailbox,$i); 
 
echo '<b>Nachricht: </b><br>'; 
echo $mail_body."<br><br>";

imap_delete($mailbox, $i); 
 
}
imap_expunge($mailbox); 
imap_close($mailbox); 
} 
?>
 
Zuletzt bearbeitet:
Ich habe vor langer Zeit mal ein Skript dafür geschrieben, was den Quelltext von E-Mails parsed und zerlegt. Dabei gehe ich da auch auf den Wechsel von Zeichensätzen ein und auf Base-64-Blöcke.
PHP:
class MailInterpreter
{
  private static $charset  = '';
  private static $encoding = '';
  private static $boundary = array();
  private static $lines    = array();
  private static $blocks   = array();
  
  #
  # Interpretiert eine E-Mail
  #
  public static function interpret ($value)
  {
    # Nachricht in Zeilen teilen
    self::$lines = explode("\n", str_replace("\r", '', $value));
    # erster Datenblock besteht per Definition aus Kopfzeilen
    self::header();
    
    # Ausnahmebehandlung: "This is a multi-part message in MIME format."
    if ((trim(current(self::$lines)) === 'This is a multi-part message in MIME format.') && (self::$boundary !== array()))
    {
      next(self::$lines);
    }
    
    # verarbeitet die Zeilen
    while (list(, $line) = each(self::$lines))
    {
      # Grenze => Kopfzeilen
      if ($line === '--' . end(self::$boundary))
      {
        self::header();
        continue;
      }
      # Grenze (Ende) => entfernen
      elseif(trim($line) === '--' . end(self::$boundary) . '--')
      {
        array_pop(self::$boundary);
        
        if(end(self::$boundary) === false)
        {
          break;
        }
        continue;
      }
      
      # Klartext => Text
      self::body();
    }
    
    $blocks = self::$blocks;
    
    # alle klasseninternen Variablen zurücksetzen
    self::$charset  = '';
    self::$encoding = '';
    self::$boundary = array();
    self::$lines    = array();
    
    # Interpretierte Datenblöcke ausgeben
    return $blocks;
  }
  
  #
  # Verarbeitet Zeilen als Kopfzeilen
  #
  private static function header ()
  {
    # Zeilen als Kopfzeilen verarbeiten
    while (list(, $line) = each(self::$lines))
    {
      # Leerzeile => Ende der Kopfzeilen
      if (trim($line) === '')
      {
        if ($content !== null)
        {
          $specification[] = self::encoding_and_charset($content);
        }
        self::$blocks[] = array(1, $specification);
        return;
      }
      
      # gehört zur vorherigen Angabe
      if (($line[0] === ' ') || ($line[0] === "\t"))
      {
        $content .= ' ' . trim($line);
        continue;
      }
      
      # neue Angabe
      # -- aktuelle Angabe speichern
      # -- neue Angabe beginnen
      if ($content !== null)
      {
        $specification[] = self::encoding_and_charset($content);
      }
      
      $content = trim($line);
    }
  }
  
  #
  # Verarbeitet Zeilen als Text
  #
  private static function body ()
  {
    # internen Zeiger um einen Eintrag zuruecksetzen
    prev(self::$lines);
    
    # Zeilen als Text verarbeiten
    while (list(, $line) = each(self::$lines))
    {
      # wenn die Zeile eine Grenze darstellt, wird der Datenblock gespeichert
      if ((trim($line) === '--' . end(self::$boundary)) || (trim($line) === '--' . end(self::$boundary) . '--'))
      {
        # Datenblock speichern
        if (trim($content) !== '')
        {
          self::$blocks[] = array(2, self::charset(self::encoding($content)));
        }
        
        # internen Zeiger um einen Eintrag zurücksetzen
        prev(self::$lines);
        return;
      }
      
      # neuen Datenblock beginnen oder an bestehenden anhaengen
      if($content === null)
      {
        $content = $line;
      }
      else
      {
        $content .= "\n" . $line;
      }
    }
    
    # alle Zeilen wurden verarbeitet
    if (trim($content) !== '')
    {
      self::$blocks[] = array(2, self::charset(self::encoding($content)));
    }
  }
  
  #
  # Kodiert einen Text in Klartext
  #
  private static function encoding ($value)
  {
    if (self::$encoding === 'quoted-printable')
    {
      $value = quoted_printable_decode($value);
    }
    
    return $value;
  }
  
  #
  # Wandelt den Zeichensatz in UTF-8 um
  #
  private static function charset ($value)
  {
    return iconv(self::$charset, 'utf-8', $value);
  }
  
  #
  # Ermittelt die Kodierung und den Zeichensatz aus einer Kopfzeile
  #
  private static function encoding_and_charset ($value)
  {
    # Zeichensatz und Kodierung ermitteln
    if (substr($value, 0, 14) === 'Content-Type: ')
    {
      # Grenze ermitteln
      if (preg_match('/boundary=("(.*)"|.*)/', $value, $match) === 1)
      {
        if (isset($match[2]) === true)
        {
          self::$boundary[] = $match[2];
        }
        else
        {
          self::$boundary[] = $match[1];
        }
      }
      
      # Zeichensatz ermitteln
      if (preg_match('/charset=("(.*)"|.*)/', $value, $match) === 1)
      {
        if (isset($match[2]) === true)
        {
          self::$charset = $match[2];
        }
        else
        {
          self::$charset = $match[1];
        }
      }
    }
    # Zeile mit der Kodierungsangabe suchen
    elseif (substr($value, 0, 27) === 'Content-Transfer-Encoding: ')
    {
      self::$encoding = substr($value, 27);
    }
    
    return $value;
  }
}
 
Hallo,

ich bin auch auf der suche eine Email richtig zu interpretieren,...

Da ich leider noch nicht so gut mir Klassen umgehen kann, verstehe ich nicht ganz wie ich die Klasse einbinden kann!

klar
PHP:
include('MailInterpreter.class.php');

aber mit welchen Befehl wende ich diese dann wo an?

Vielen Dank für die Tipps!

Gruß Baer
 
Zuletzt bearbeitet:
Diese Klasse von crack hat alles statische Funktionen. Ergo einen einfachen Statischen Aufruf
PHP:
//Hab aber keine Ahnung was bei dieser Klasse $value ist und was genau als $result zurückkommt. 
//Die Dokumentaierung ist in dieser Hinsicht mangelnd.
$result = MailInterpreter::interpret($value);
 
Vielen Dank,

leider macht die Klasse nicht das, was ich mir erhofft habe,... bzw. ich kann damit nicht umgehen!

zu meinem Problem:
ich mache einen IMAP abruf und erhalte über diesen befehl
PHP:
$body = imap_body($mbox,$overview->msgno);
echo "<pre>".$body."</pre>";
folgendes:
Code:
--_000_70DA0C594B96434684762CC7B68465410C1D9815BAERSERVERedvba_
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

Dieses mal mit etwas l=E4ngeren text um zu testen ob die zeile wieder abgeb=
rochen wird! Ca. 69 zeichen muss ich in eine zeile bringen um zu wissen ob =
es funktioniert! Jetzt sollte ich auf jeden fall etwas mehr zeichen haben, =
ich teste jetzt noch ein paar html funktionen wie fettschrift und zentriert=
!


Test fett

Test center

--_000_70DA0C594B96434684762CC7B68465410C1D9815BAERSERVERedvba_
Content-Type: text/html; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable









Dieses mal mit etwas l=E4ngeren text um zu testen ob= die zeile wieder abgebrochen wird! Ca. 69 zeichen muss ich in eine zeile b= ringen um zu wissen ob es funktioniert! Jetzt sollte ich auf jeden fall etw= as mehr zeichen haben, ich teste jetzt noch ein paar html funktionen wie fettschrift und zentriert!

 

 

Test fett

 

Test ce= nter




--_000_70DA0C594B96434684762CC7B68465410C1D9815BAERSERVERedvba_--
oder
Code:
--_000_70DA0C594B96434684762CC7B68465410C1D87FDBAERSERVERedvba_
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

hallo

--_000_70DA0C594B96434684762CC7B68465410C1D87FDBAERSERVERedvba_
Content-Type: text/html; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable









hallo




--_000_70DA0C594B96434684762CC7B68465410C1D87FDBAERSERVERedvba_--
auch
Code:
kann mir bitte jemand die internet-adresse schicken? =3D) Ich w=C3=BCrde mi=
ch sehr freuen... Schaf


Um diese Email anzeigen zu k=C3=B6nnen, ben=C3=B6tigen Sie einen HTML f=C3=
=A4higen Email=20
Client!

Leider habe ich keinen Plan wie ich damit umgehen soll damit das richtig Formatiert ist,... mit etwas filterarbeit habe ich zwar schon einiges herausfiltern können,... aber bei einer anderen Email (von einem Anderen Client) kommt wieder etwas ganz anderes an!

diese Funktionen habe ich schon einzeln und in Kombination getestet,... leider ohne vernünftigen erfolg!
PHP:
	$body = htmlentities($body);
	$body = htmlspecialchars ($body);
	$body = nl2br($body);
	$body = imap_utf8($body);
	$body = imap_qprint($body);
	$body = str_replace("\n", "<br>", $body);
	$body = mb_convert_encoding($body, 'iso-8859-1');

damit bin ich etwas weiter gekommen,...
http://www.tutorials.de/php/237298-imap_body-formatiert-und-mit-umlauten-ausgeben.html

aber eine schöne Formatierte ausgabe in HTML oder nur TEXT,... wie es in der Email (wie bei den Maildiensten ja auch funktioniert) habe ich noch nicht hinbekommen :/

Danke für die Hilfe schon im vorraus!

Gruß
Baer
 
Zuletzt bearbeitet:
@Yaslaw: Wenn du dir einmal den Quelltext ansiehst, der einer jeden E-Mail zugrunde liegt, also das, was eigentlich übermittelt wird, dann hast du genau das, was meine Methode als Argument haben will.

@JesusFreak: Wenn du mal das, was du als Mail-Quelltext beigetragen hast, nimmst, und es meiner Methode übergibst, dann wirst du sehen, dass meine Klasse die Kodierung zu UTF-8 automatisch vor nimmt. Allerdings musste ich gerade feststellen, dass meine Klasse auf etwas nicht eingeht: und zwar, dass als erste Zeile bereits eine Boundary kommt, was eigentlich sein dürfte. Daher werde ich gleich einmal probieren dafür eine Änderung einzufügen.
 
Zuletzt bearbeitet:
@Yaslaw: Wenn du dir einmal den Quelltext ansiehst, der einer jeden E-Mail zugrunde liegt, also das, was eigentlich übermittelt wird, dann hast du genau das, was meine Methode als Argument haben will.
Naja, da ich noch nie mit PHP und mails gearbeitet habe, weiss ich nicht was $value ist und was der Rückwert ist (ich meine ohne den Code zu lesen - nur anhand des Kommentars).
Darum macht es Sinn in der Beschreibung der MEthode @param und @return ganz kurz zu erläutern
zB:
PHP:
    /**
     * $_FILE auswerten
     * @param <Integer>        id bei einem Multiupload-Feld
     * @return <Array>         Alle ausgelesenen Werte als Array
     */
    protected function getFileProperties($id = 0){
...

Somit war meine posting nur eine Anleitung wie man eine statische Klasse verwendet.....
 
@crack wie genau binde ich die klasse ein?

PHP:
include('MailInterpreter.class.php');  

... imap empfang

$body = imap_body($mbox,$overview->msgno);

$result = MailInterpreter::interpret($body);  

echo $result;

Code:
Notice: Undefined variable: content in /var/www/web1053/html/msg/MailInterpreter.class.php on line 93
93:       if ($content !== null)

Notice: Undefined variable: content in /var/www/web1053/html/msg/MailInterpreter.class.php on line 128
128:       if($content === null)

irgendwas mach ich falsch!?

Danke für eure Hilfe

Gruß Baer

Nachtrag:
natürlich nicht echo sondern print_r,... ändert aber nichts an den fehlern!
 
Zuletzt bearbeitet:
Zurück