Šiame straipsnyje apžvelgsiu daugiaformačių laiškų, bei laiškų su priedais (attachments) siuntimą. Kad suprastumėt kaip tai daroma, jums iš pradžių reikės susipažinti su MIME formatu, ką vėliau ir padarysime. Dabar pažvelkime į paprasto laiško siuntimą, naudojant funkciją mail().

Pavizdys iš php.net:

$to      = 'nobody@example.com';
$subject = 'the subject';
$message = 'hello';
$headers = 'From: webmaster@example.com' . "\\r\\n" .
       'Reply-To: webmaster@example.com' . "\\r\\n" .
       'X-Mailer: PHP/' . phpversion();

mail($to, $subject, $message, $headers);

Bene svarbiausia dalis čia – header’iai. Headeriai yra plačiai naudojami ir kitų aplikacijų kūrime, bet čia jau kita tema. Pašto headeriuose nurodome siuntėją, atsakymo adresą, kliento tipą, dokumento (turinio) tipą ir t.t. Pradedantiesiems, tai bene sunkiausia dalis, todėl dėliojant headerius patartina pasitikslinti su kitais šaltiniais. Siunčiant daugiadales (multipart) žinutes taip pat nurodysime reikalingus headerius. Daugiadalio laiško sudėtis tokia (MIME formatas):

  1. laiško headeriai
  2. sienelė (boundary)
  3. konkrečios dalies headeriai, po jų, standartiškai – tuščia eilutė
  4. tos dalies turinys
  5. žr. 2
  6. žr. 3
  7. žr. 4
  8. žr. 2
  9. ir t.t.
  10. laiškas užbaigiamas sienele

Laiško headerius jau aptarėme, dabar išsiaiškinsime, kas tas boundary. Boundary – speciali eilutė, skirta atskirti turinio dalims (pvz.: paveiksliuką nuo teksto). Eilutė turi būti unikali ir nebūti kaip turinio dalis (akivaizdu). Sienelei sugeneruoti galima panaudoti tokį kodą:

//parašas. galite sienelę supersonalizuoti :)
$signature = 'p4i-rules-';
//sugeneruojam simbolių eilutę, unikalumui užtikrinti
$hash = md5(time());
//sujungiame parašą ir eilutę
$boundary = $signature.$hash;

Laiško dalies headeriuose reiktų nurodyti dalies turinio tipą (Content-type) ir turinio koduotę (Content-Transfer-Encoding). Papildomus headerius norodome pagal poreikį.

Kokio tipo laiškas bebūtų, jis sudarytas tik iš (surprise!) teksto/simbolių. Jei siunčiamas ne tekstas, duomenys užkoduojami base64 koduote. (Taip, base64 tam ir skirtas, o ne slaptažodžių “saugojimui” ar unFriendly urls gamybai). Failo užkodavimui galite naudoti tokį būdą:

$file = 'rozhes.gif';
//atsidarom failą (binary mode)
$f = fopen($file, 'rb');
//nuskaitom failą (didesniems failams geriau naudoti ciklą)
$c = fread($f, filesize($file));
//daliname koduotą eilutę į gabalus
$encoded = chunk_split(base64_encode($c));

Dalių pavyzdžiai:

Teksto dalis:
Atkreipkite dėmesį į du brūkšnelius prieš sieneles.

--p4i-rules-53a5ddb48feded5bec130878c979f778
Content-Type: text/plain; charset=UTF-8;
Content-Transfer-Encoding: 7bit

labas, maryte! šiandien 8 prie medžio! lauksiu!

Paveikslėlio (priedo) dalis:

--p4i-rules-53a5ddb48feded5bec130878c979f778
Content-type: image/gif; name="rozhes.gif"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="rozhes.gif"

R0lGODlhAgACAIABAP8AAAAAACH5BAEKAAEALAAAAAACAAIAAAIChFEAOw==

O dabar galime viską sujungti:

$signature = 'p4i-rules-';
$hash = md5(time());
$boundary = $signature.$hash;

$to      = 'maryte@example.com';
$subject = 'meet\'as';
$headers = 'From: petriukas@example.com'."\\r\\n" .
       'Reply-To: petriukas@example.com'."\\r\\n" .
       'MIME-Version: 1.0'."\\r\\n".
       'Content-Type: multipart/mixed; boundary="'.$boundary.'"'; //čia dviejų brūkšnelių nededame
       //šioje vietoje tuščią eilutę paliks pati mail funkcija

$message = '--'.$boundary.'
Content-Type: text/plain; charset=UTF-8;
Content-Transfer-Encoding: 7bit

labas, maryte! šiandien 8 prie medžio! lauksiu!

--'.$boundary.'
Content-type: image/gif; name="rozhes.gif"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="rozhes.gif"

R0lGODlhAgACAIABAP8AAAAAACH5BAEKAAEALAAAAAACAAIAAAIChFEAOw==
--'.$boundary.'';

mail($to, $subject, $message, $headers);

Išsisiuntę sau tokį laišką, gausime tekstą ir prikabintą paveiksliuką (2×2 px). Pasinaudojus vaizduote (ir headeriais), galima siųsti įvairiausius laiškus (pvz.: html su paveikslėliais ir stiliais (css)). Tik nepiktnaudžiaukit ;)