Generowanie załącznika w locie by dołączyć go do email'a - bez zapisu na dysku serwera.

Jozdowska Edyta · 04 Styczeń 2020

1.Wysyłanie maila z php

Temat bardzo prosty. Bo co to znaczy wysłać maila w php? Mamy funkcję mail. Każdy co ma styczność z php powinien ją znać. Jeśli nie w dokumentacji PHP można o niej przeczytać więcej. Można też użyć klasy PHPMailer 1. Rozwiązań jest dużo.

W momencie, gdy mamy załączyć plik nie zapisany nigdzie musimy go wygenerować. Poniższa klasa służy właśnie do wygenerowania załącznika z tablicy danych i załączenia go w pamięci do naszego maila.

2.Klasa do wysyłania maila

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
class SendMail{
  public $to; // adres na który wiadomość zostanie wysłana
  private $senderEmail; // kto wysyła wiadomość
  private $senderName;// ładna nazwa nadawcy
  private $replyTo;// do kogo odpowiedzieć 
  private $multipartSep; // separator by załączyć plik w md5
  private $headers;// wysyłane nagłówki wiadomości
  private $attachmentName;// nazwa załącznika
  private $attachment;// załącznik
  
  function __construct() {
          //te dane ustawiam tutaj, jednak mogły by one równie dobrze zostać ustawione później.

          $this->senderEmail = "fromMail@domain.com";
          $this->senderName = "My really cool name";
          $this->replyTo = $this->senderEmail;
          $this->multipartSep = '-----'.md5(time()).'-----';
          $this->attachmentName = 'myCoolNameOfAttachment';
         
         $this->setHeaders();
  }

  function setHeaders(){

    $this->headers = array(
      "From:$this->senderName<$this->senderEmail>",
      "Reply-To: ".$this->replyTo,
      "Content-Type: multipart/mixed; boundary=\"$this->multipartSep\""
    );

  }

  function sendMail($data){

    /* input :
      $data = [
        'to'=> String e-mail
        'data'=> Max two dimensional Array
        'message'=> String
        'subject'=> String
      ];
    */

    extract($data);

    $this->attachment = chunk_split(base64_encode($this->array2csv($to)));
    
    if(empty($this->attachment)) return false;
    
    $subject = '=?UTF-8?q?' . quoted_printable_encode($subject) . '?=';	

    $csvName= $this->attachmentName.date("Y_m_d_H_i_s").'.csv';

    $body = "--$this->multipartSep\r\n"
      . "Content-Type: text/html; charset=utf-8; format=flowed\r\n"
      . "Content-Transfer-Encoding: 7bit\r\n"
      . "\r\n"
      . $message."\r\n"
      . "--$this->multipartSep\r\n"
      //. "Content-Type: application/vnd.ms-excel\r\n"
      . "Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\r\n"
      . "Content-Transfer-Encoding: base64\r\n"
      . "Content-Disposition: attachment; filename=\"".$csvName."\"\r\n"
      . "\r\n"
      . "$this->attachment\r\n"
      . "--$this->multipartSep--";
      
      try {
        
        mail($to, $subject, $body, implode("\r\n", $this->headers));

        echo 'Mail wysłany';

      } catch (Exception $e) {

          echo 'Błąd wysłania maila: ',  $e-->getMessage(), "\n";
      }
  }

  function array2csv($data, $delimiter = ',', $enclosure = '', $escape_char = "\\"){
    
    //Funkcja do wygenerowania załącznika z danych tablicy maksymalnie dwu wymiarowej

    $f = fopen('php://memory', 'rw+');
    //nasze dane są jako tablica
    foreach ($data as $key => $item) {		
      
      if(is_array($item)){          
          foreach ($item as $k=>$i) {            
              array_push($data,$i);          
          }
          unset($data[$key]);	
      }        
    }

    fputcsv($f, $data, $delimiter, chr(0), $escape_char);
    rewind($f); //wróć do początku pliku
    return rtrim(stream_get_contents($f));
  }
}

3.Użycie

1
2
3
4
5
6
7
8
9
10
$o = new SendMail();
$data = [
  'to'=>'emailTo@domain.com',
  'data'=>array("a"=>"a","b"=>"b"),
  'message'=>'message',
  'subject'=>'subject'
];

$o->sendMail($data);
  1. https://github.com/PHPMailer/PHPMailer 

Jozdowska Edyta * FullStack Developer

Pisanie kodu jest moją pasją. Zajmuję się tym od przeszło 10 lat, z większą lub mniejszą intensywnością.
Piszę kod w PHP, JS, SCSS i Python. Nie stronię też od poznawania nowych, lub jak kto woli starych rozwiązań jak Jekyll oraz innych języków np. Java.

więcej o mnie