Šiame straipsnyje apžvelgsiu daugiaformačių el. laiškų bei el. laiškų su priedais (angl. attachments) siuntimą. Kad suprastumėte 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().

Pavyzdys iš .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 - antraštės (angl. headers). Jos yra plačiai naudojamos ir kitų aplikacijų kūrime, bet čia jau kita tema. Pašto antraštėse nurodome siuntėją, atsakymo adresą, kliento tipą, dokumento (turinio) tipą ir t.t. Pradedantiesiems, tai sunkiausia dalis, todėl dėliojant antraštes patartina pasitikslinti su kitais šaltiniais. Siunčiant daugiadales (angl. multipart) žinutes taip pat nurodysime reikalingas antraštes. Daugiadalio laiško sudėtis tokia (MIME formatas):

  1. laiško antraštės;
  2. sienelė (boundary);
  3. konkrečios dalies antraštės, 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 antraštes jau aptarėme, dabar išsiaiškinsime, kas ta sienelė (angl. boundary). Tai 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 antraštėse reikėtų nurodyti dalies turinio tipą (Content-type) ir turinio koduotę (Content-Transfer-Encoding). Papildomas antraštes nurodome 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: 8bit
 
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 antraštėmis), galime siųsti įvairiausius laiškus (pvz., html su paveikslėliais ir stiliais (css)). Tik nepiktnaudžiaukit ;)

Originalus straipsnis “El-pašto siuntimas su PHP: pažvelkime giliau.

Atnaujinimas 2007.08.29: eilutė “Content-Transfer-Encoding: 7bit” pakeista į “Content-Transfer-Encoding: 8bit“, po RQ pastabų. Ačiū.

Panašūs straipsniai


“El. laiškų siuntimas su PHP: pažvelkime giliau.” komentarų: 6

  1. Merė Raili

    http://phpmailer.sourceforge.net/

    sėkmės išradinėjant dviratį

  2. asterisk

    Merė Raili ++ ;)
    Visiškai sutinku, jog nėra reikalo šiais laikais knistis su mail() funkcija, kai yra toks dalykas kaip phpmailer.

  3. Armandas

    O pasimetusiems pasakysiu, kad mokėjimas pasinaudoti klase ir bendras suvokimas kaip veikia el-paštas bei kas yra MIME formatas yra du skirtingi dalykai :)
    Dar pridėsiu, kad kartais verta “išrasti” tą dviratį iš naujo. Ypač pradedantiems.

  4. Armandas

    Gerai, dėl el-pašto veikimas gal nevisai tinka, bet enyvai, tokios žinios manau yra į naudą. Klasėm tikrai dauguma išmoks pasinaudoti, o kaip ten kas padaryta - vargu ar supras be elementarių žinių ;)


  5. Armandas teisus - žinoti yra labai sveika.

    Be to, siunčiant el. laiškus reikia nepamiršti nurodyti Content-type, kuris būna text/plain arba text/html bei charset (pvz.: Content-type: text/plain; charset=utf-8).

    Norėčiau pastebėti iš savo patirties siunčiant el. laiškus, kad pvz., ne visi SMTP serveriai gerai palaiko ir perduoda UTF-8, ko pasekoje laiškas UTF-8 koduotėje gali būti sudarkytas (kaip subject, taip ir body), todėl jos patarčiau koduoti su base64 (galima ir su 8bit, bet berods PHP neturi tam funkcijos), pridedant antraštė “Content-Transfer-Encoding: base64″.

    Patarčiau nenaudoti ‘X-Mailer: PHP/’ . phpversion(); - SpamFiltrai gali jūsų nesuprasti .)

  6. Siuntinėjame laiškus » Pixel.lt

    […] jau skaitėte Armando straipsnį ir susipažinote su laiškų siuntimo pagrindais. Taigi dabar galime pakalbėti apie aukštesnę siuntimo formą, kai ne pats rašai […]

Rašyti komentarą

Jūs privalote prisijungti jeigu norite rašyti komentarą.