• User Attivo

    Invio allegati tramite newsletter php

    Ciao a tutti, ho creato una newsletter in PHP che, per evitare di far andare il server in time out, effettua un redirect sulla pagina ogni N indirizzi email e continua da dove ha lasciato.

    Ho questo codice che verifica se nella form di invio email è stato inserito un allegato e lo aggiunge nelle intestazioni del messaggio:
    [PHP]if (is_uploaded_file($allegato){
    // Apro e leggo il file allegato
    $file = fopen($allegato,'rb');
    $data = fread($file, filesize($allegato));
    fclose($file);

          // Adatto il file al formato MIME base64 usando base64_encode 
          $data = chunk_split(base64_encode($data)); 
         
          // Genero il "separatore" 
          // Serve per dividere, appunto, le varie parti del messaggio. 
          // Nel nostro caso separerà la parte testuale dall'allegato 
          $semi_rand = md5(time()); 
          $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x"; 
          $intestazioni= "From:".$mittente; 
          // Aggiungo le intestazioni necessarie per l'allegato 
          $intestazioni .= "\nMIME-Version: 1.0\n"; 
          $intestazioni .= "Content-Type: multipart/mixed;\n"; 
          $intestazioni .= " boundary=\"{$mime_boundary}\""; 
       /* // costruiamo le intestazioni specifiche per il formato HTML 
          $intestazioni .= "X-Mailer: PHP/" . phpversion();*/ 
        // Definisco il tipo di messaggio (MIME/multi-part) 
          $msg .= "This is a multi-part message in MIME format.\n\n"; 
     
        // Metto il separatore 
          $msg .= "--{$mime_boundary}\n"; 
     
        // Questa è la parte "testuale" del messaggio 
          $msg .= "Content-Type: text/html; charset=\"iso-8859-1\"\n"; 
          $msg .= "Content-Transfer-Encoding: 7bit\n\n"; 
          $msg .= stripslashes($testo) . "\n\n"; 
    
        // Metto il separatore 
          $msg .= "--{$mime_boundary}\n"; 
     
        // Aggiungo l'allegato al messaggio 
          $msg .= "Content-Disposition: attachment;\n"; 
          $msg .= " filename=\"{$allegato_name}\"\n"; 
          $msg .= "Content-Transfer-Encoding: base64\n\n"; 
          $msg .= $data . "\n\n"; 
     
        // chiudo con il separatore 
          $msg .= "--{$mime_boundary}--\n";  [/PHP]
    

    Dove $allegato è inizializzata così

    [PHP]if(isset($_FILES['allegato']['tmp_name'])){
    $allegato = $_FILES['allegato']['tmp_name'];
    $allegato_type = $_FILES['allegato']['type'];
    $allegato_name = $_FILES['allegato']['name'];
    } [/PHP]

    Ma nel secondo redirect della pagina, $_FILES['allegato']['tmp_name'] è vuoto e mi restituisce errore e dal secondo invio non manda più l'allegato.

    Sapreste aiutarmi per caso?
    Grazie 🙂


  • User Attivo

    $_FILES viene valorizzato mediante il form, quindi quando esegui il redirect, la pagina non riceve più il form quindi è vuoto.
    A te servirebbe memorizzare il file sul server ed allegare quel file all'email, in questo modo ogni volta che esegui il redirect, il file è sul server e quindi riesce ad inviare l'allegato.


  • Super User

    Ciao talkoman,

    Aggiungo a quanto scritto da codencode che ti mancano delle intestazioni.
    Ad esempio dove sono

    Message-ID:
    Date:

    ?

    Fai attenzione a queste cose che fanno aumentare il tuo spam score.

    Ti consiglio anche di sostituire i numerosi operatori di assegnazione concatenato che hai usato con un singolo heredoc
    php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc


  • User Attivo

    Il consiglio di enigma nel ricorrere a heredoc lo vedo positivamente. Infatti dopo la lettura del suo post ho ristrutturato di un modulo che forse è sufficientemente articolato ed ora focalizzando l'attenzione solo sulla parte di preparazione del messaggio e-mail appare più chiara.
    Invece non so se ci sia una differenza di prestazioni tra le due versioni perché avendolo appena finito non ho avuto tempo sia di fare qualche ricerca, che di fare delle prove di benchmarck.
    Per ora l'unico problema che non ho risolto è come fare un ciclo foreach all'interno di un heredoc, ma ho l'impressione che non si possa fare.

    L'unica obiezione che sollevo ad enigma riguarda l'intestazione "Message-ID:" poiché ho notato che almeno sul mio server viene automaticamente inserita. Pertanto ne avrei un'altra imprecisa (trovata su un forum) perché non ho dedicato molto tempo a trovare specifiche ufficiali.
    In definitiva il mio consiglio è di vedere prima quali sono le intestazioni già messe dal server (grazie alle configurazioni di php.ini) e poi aggiungere solo quelle mancanti.


  • Super User

    Ciao Mente,

    Non importa se sia tu o il tuo MTA ad aggiungere l'intestazione Message-ID. Se il tuo MTA è configurato per aggiungerla se mancante, tanto meglio.
    L'importante è che l'email non arrivi senza all'MTA di gmail, hotmail, yahoo ecc. o ci potrebbe essere come conseguenza +1 nello spam score.

    @MenteLibera said:

    Pertanto ne avrei un'altra imprecisa (trovata su un forum) perché non ho dedicato molto tempo a trovare specifiche ufficiali.

    Non puoi usare lo stesso Message-ID più volte, deve essere un valore nuovo ogni volta.

    La pagina jwz.org/doc/mid.html spiega come generare Message-ID


  • User Attivo

    @enigma said:

    Non puoi usare lo stesso Message-ID più volte, deve essere un valore nuovo ogni volta.

    Infatti sulla conversazione di quell'altro forum nell'identificativo indicavano di mettere la data e l'MD5 applicato alla concatenazione dell'indirizzo del mittente con quello del destinatario, ma se ci pensi bene quel suggerimento si rileva inutile quando lo stesso destinatario è registrato più volte (magari per dimenticanza o peggio per ripicca da parte di altri) in abbinamento al mancato controllo di doppioni fatto sul DB, quest'ultima verifica non mi sembra che sia suggerita in nessun tutorial consultati finora. Infatti il server potendo mandare più e-mail al secondo la probabilità che in tale periodo di tempo avvenisse più di un invio genererebbe almeno un doppione che ricadrebbe in quella criticità.

    @enigma said:

    La pagina jwz.org/doc/mid.html spiega come generare Message-ID

    Grazie per l'approfondimento.