Bastian: Maximale Größe eines Zip-Archivs bestimmen

Hallo,

ein zweigeteilte Frage, ich packe derzeit "zu generierenden Dateien (pdfs)" in eine Zip-Datei und versende die per email.

Nun erhielt ich soeben die Meldung:

A message that you sent was longer than the maximum size allowed on this
system. It was not delivered to any recipients.

Heißt also, ich hätte besser mehrere Dateien daraus gemacht und mehrer Emails versendet. Geht sowas überhaupt? Also quasi dem php-Script mitteilen, dass es aus einer beliebigen Anzahl von Dateien eines Verzeichnisses n Zip-Archive mit max. x MB Datenmenge machen soll und diese dann anschließend in n Emails versenden soll??

Mein bisheriger Quellcode ist der:

$zip_name = $dir."/".$vonbis.".zip";
// Verzeichnis auslesen
$dateien = scanDir($dir);
// Neue Instanz der ZipArchive Klasse erzeugen
$zip = new ZipArchive;
// Zip-Archiv erstellen
$status = $zip->open($zip_name, ZipArchive::CREATE);
if ($status === TRUE) {
 // Dateien ins Zip-Archiv einfügen
 foreach ($dateien as $datei) {
     if ($datei != "." && $datei != "..") {
         $zip->addFile($dir."/".$datei,$datei);
     }
 }
// Zip-Archiv schließen
 $zip->close();
}


//Klasse einbinden
require_once('./class.phpmailer.php');

//Instanz von PHPMailer bilden
$mail = new PHPMailer();
$mail->IsHTML(true);
$mail->CharSet = "ISO-8859-1";
//Absenderadresse der Email setzen
$mail->From = $absender;
$mail->FromName = "Tester";
$mail->AddAddress($adresse);
//Betreff der Email setzen
$mySubject = "Text $var1 vom $von_Datum bis $bis_Datum";

$mail->Body = $text;

//Eine Datei vom Server als Attachment anhängen
$mail->AddAttachment($zip_name,"meineDatei.zip");

$mail->Send();
  1. A message that you sent was longer than the maximum size allowed on this system. It was not delivered to any recipients.

    Das Problem ist so alt wie die Email-Protokolle. Offenbar hat mindestens einer der Mailserver der Empfänger die Annahme des Mails wegen dessen Übergröße verweigert.

    Lösungen:

    Entweder

    • ermittelst Du (wie auch immer) die maximale Größe der Anhänge für jeden Mail-Server aller Benutzer und splittest bei Bedarf, versende dann mehrere Mails.

    oder

    • lege die Zips ab 1 MB (das geht erfahrungsgmäß immer) in einen Dowload-Ordner, vergib Passwörter (die vor einem Download abgefragt werden) und verschicke den Link nebst Passwort.

    oder

    • splitte ab 1 MB, versende dann mehrere Mails.

    Hinweis:

    PDFs lassen sich kaum packen. Die Gesamtgröße des Zips entspricht in etwa der Summe aller darin enthaltener Dateien - kann aber (wegen im zip enthaltener Meta-Daten) sogar geringfügig größer sein.

    Wenn Du also keine Anhänge größer als 1 MB versenden willst, dann nimm ab einer Summe von 900.000 Bytes an, dass das Zip größer wird und gehe so vor, wie für den Fall, das es mehr als 1MB wird, geplant hast.

    Geht sowas überhaupt? Also quasi dem php-Script mitteilen, dass es aus einer beliebigen Anzahl von Dateien eines Verzeichnisses n Zip-Archive mit max. x MB Datenmenge machen soll und diese dann anschließend in n Emails versenden soll??

    Wie „mitteilen“? Das muss man programmieren. Und das ist vorliegend trivial. Freilich muss man dazu wissen was dass offenbar abgeschriebene Zeug überhaupt macht. Also lerne wenigstens die bittersten Grundlagen der von Dir verwendeten Programmiersprache. Anders geht es nicht!

    1. Hallo Willi,

      Das Problem ist so alt wie die Email-Protokolle. Offenbar hat mindestens einer der Mailserver der Empfänger die Annahme des Mails wegen dessen Übergröße verweigert.

      Ja, so wird es sein.

      • splitte ab 1 MB, versende dann mehrere Mails.

      Hm, 1 MB ist wirklich übelst wenig.

      PDFs lassen sich kaum packen. Die Gesamtgröße des Zips entspricht in etwa der Summe aller darin enthaltener Dateien - kann aber (wegen im zip enthaltener Meta-Daten) sogar geringfügig größer sein.

      Mir gehts bei den PDFs weniger darum, sie durchs packen kleiner zu machen, als mehr darum, nicht hunderte Dateianhänge zu versenden, sondern nur einen oder nur wenige.

      Wie „mitteilen“? Das muss man programmieren. Und das ist vorliegend trivial. Freilich muss man dazu wissen was dass offenbar abgeschriebene Zeug überhaupt macht. Also lerne wenigstens die bittersten Grundlagen der von Dir verwendeten Programmiersprache. Anders geht es nicht!

      Na, nun sei doch nicht so böse mir mir, Willi. 😉
      Geht doch nur darum, dass ich nicht weiß, ob die php-Zip-Klasse dafür bereits irgendwelche Methoden bereit stellt oder ob ich das "zu Fuss" programmieren muss.
      Ist mir halt schon oft passiert, dass ich etwas umständlich zu Fuss programmiert habe und anschließend z.b. hier erfahren habe, dass ich mir das alles hätte sparen können, weils sowas schon quasi fertig gibt.

      Im Moment tendiere ich sogar zu einer etwas anderen Lösung:

      Denn bisher ging ich immer davon aus, per cron einmal/Zeiteinheit eine Email mit den gezippten Dokumenten heraus zu schicken. Aber vielleicht wäre es viel schlauer, den cron täglich zu starten und in unregelmäßigen Abständen eine Email mit einer max. großen Zip zu versenden. Naja, aber kunden freundlich ist auch anders. 😑

      Also meinst Du, es ist tatsächlich so, dass ich innerhgalb der Schleife anhand der kummulierten PDF-Größen (oder etwa der bisherigen Zip-Datei?) entscheide, wann ich eine neue Zip anfange und später je Datei eine Email versende?

      Quasicode:

      foreach (Dateiarray AS Einzeldatei) {
          Ab_in_die_Zip
          Größe_der_Zip_messen
          Wenn > 900KB {
              close_zip_und_mailversand
              Dann nächste Zip
          }
      }
      

      Danke für Deinen Hilfe 🙂

      Bastian

      1. Hm, 1 MB ist wirklich übelst wenig.

        Ich bin mit Datenträgern „aufgewachsen“, die konnten gar nicht so viel speichern.

        Stell Dir mal vor, Du seist IT-Vorstand bei einem Dax-Konzern mit 20.000 Angestellten. jeder von denen bekommt jeden Werktag von nur 100 solche Mails mit einem Anhang von 1MB. In zwanzig Prozent der Fälle erfolgt eine Weiterleitung, weil die abwesend sind…

        20000*(100+20+20)*300 = 840000000 Mails

        Das sind dann

        840.000.000 Mails * 1MB/Mail
        =  840.000.000.000.000 Bytes
        =  840 Terabytes
        

        (per Jahr)

        In „guten“ Jahren also „gern“ auch mal ein Petabyte.

        Und jetzt erkläre den Aktionären, warum (zum Teufel!) der Konzern das Geld in die IT statt in die sehnlichst erwartete Dividende steckt und warum also die Aktie (und somit das Vermögen der Aktionäre) wegen des schlechten KGV (Kurs-Gewinn-Verhältnisses) an der Börse „abgekackt“ ist.

  2. @@Bastian

    A message that you sent was longer than the maximum size allowed on this
    system. It was not delivered to any recipients.
    

    Heißt also, ich hätte besser mehrere Dateien daraus gemacht und mehrer Emails versendet.

    Nein, das heißt, dass du nicht die Posteingänge der Empfänger vollstopfen solltest.

    Geht die E-Mail nicht einfach als Text?

    Oder – wenn’s etwas formatierter sein soll – als HTML-Mail?

    Wenn die Empfänger tatsächlich das PDF benötigen, wie Raketenwilli sagte: PDF auf deinen Webserver tun und den Link per E-Mail verschicken.

    🖖 Живіть довго і процвітайте

    --
    When the power of love overcomes the love of power the world will know peace.
    — Jimi Hendrix
    1. Hi Gunnar,

      Wenn die Empfänger tatsächlich das PDF benötigen, wie Raketenwilli sagte: PDF auf deinen Webserver tun und den Link per E-Mail verschicken.

      Das ist womöglich eine echt gute Idee.

      Hat aber den Nachteil, dass ich alle diese Zips vorhalten muss, mir also damit den Server ein Stückweit vollspame. Denn ich selber benötige die Dateien echt nicht.

      Abhilfe wäre, dass ich die Zips nicht (oder nicht dauerhaft) hartcodiert dort ablege, sondern bei Bedarf per Link dynamisch erst erzeuge und nen Tag später wieder lösche. So könnte der Mailempfänger sich auch Jahre später nochmal die Zips per Link selber jeweils für einen Tag generieren.

      Basti

      1. Abhilfe wäre, dass ich die Zips nicht (oder nicht dauerhaft) hartcodiert dort ablege, sondern bei Bedarf per Link dynamisch erst erzeuge und nen Tag später wieder lösche. So könnte der Mailempfänger sich auch Jahre später nochmal die Zips per Link selber jeweils für einen Tag generieren.

        Jepp. Genau so.

  3. Lieber Bastian,

    denke immer daran: E-Mail-Anhänge werden technisch bedingt um 50% größer. Ein Anhang von 1MB Datenmenge wird real in der E-Mail 1.5MB groß. Dazu kommt, dass Du nicht wissen kannst, welche Größenbeschränkungen der empfangende Mailserver einer einzelnen Mail auferlegt.

    Deswegen kann es sinnvoll sein, eben keine ZIP-Dateien zu versenden, sondern Links. Und das Script, welches die ZIP-Dateien generiert, kann dann vielleicht auch entsprechend präparierte Links verarbeiten, um die ZIP-Dateien dann zum Download zu erzeugen, anstatt sie als Anhänge in eine Mail zu packen.

    Liebe Grüße

    Felix Riesterer