Балада про php та електронну пошту.
Досить давно зіткнувся з проблемою відправки електронної пошти з php. З того часу знайшов декілька підходів до вирішення цієї проблеми та дізнався про різноманітні підводні камені, що можуть Вам, Шановний Читач, зустрітись в повсякденній роботі.
Розпочну я з того, яким чином просто можна відправляти повідомлення за допомогою php
Функція mail()
Найпростішим способом для надсилання пошти є використання стандартної для *nix систем утилітки sendmail вірніше різноманітних її замінників, що можуть бути присутні в системі. Проте, для написання програмного коду на php здавалось би не мало б бути жодної різниці. Що до проблем, які можуть виникати я ще повернусь. Одразу скажу, що з першого погляду їх не повинно бути та так воно й є в більшості випадків.
В php присутня функція mail(), що дозволяє відправляти листи на вказану адресу:
bool mail ( string to, string subject, string message [, string additional_headers [, string additional_parameters]])
Обов'язковими параметрами є:
- email отримувача;
- заголовок листа;
- текст повідомлення.
А необов'язкові:
- додаткові заголовки;
- додаткові параметри командного рядка.
Якщо лист було поставлено в чергу для надсилання, то функція mail() повертає true. В противному разі false. Найбільш простий приклад її використання:
mail('test@grandse.org.ua', 'Subject', "Line 1\nLine 2\nLine 3");
А що ж тоді робити з додатковими параметрами? Ну про другий я нічого розповідати не буду, оскільки можливі значення та правила роботи будуть залежати суто від конкретної реалізації утиліти для надсилання пошти на сервері. До того ж я ще жодного разу не чув про випадок, коли використання цього параметра було б необхідним чи взагалі про те, щоб ним хтось скористався. Однак не завадить знати, що є й така можливість.
А ось на заголовках листа я зупинюсь детальніше.
Заголовки для повідомлення
Додаткові заголовки листа можуть бути використані для опису параметрів листа, вказуючи властивості інформації, що в ньому зберігається. Вони мають бути розділені переходом на новий рядок шляхом використання комбінації "\r\n". Наприклад так:
mail('test@grandse.org.ua', 'subject', 'Some text message',
'From: grandse@grandse.org.ua '."\r\n".'X-Mailer: PHP/'. phpversion());
Для отримувача лист матиме вигляд:
From: grandse@grandse.org.ua
To: test@grandse.org.ua
Subject: Hello from John!
Date: Wed, 14 Jan 2009 22:18:47 -0300
X-Mailer: PHP/5.2.4
Message-ID: <1234@local.machine.example>
Some text message
Фактично кожен лист, що відправляється повинен мати подібний вигляд. Як можна побачити функція mail() спрощує генерацію листа. Правила оформлення листів електронної пошти описані стандартом RFC-822. На деяких можливостях я зупинюсь детальніше.
From - адреса відправника листа у форматі:Проблема перша - кирилічні символи
Перша проблема з якою стикався мабуть кожен, хто працював напряму з функцією mail() - проблеми з кирилічними символами. Вірніше з кодуванням. Першим правилом, що дозволить уникнути проблем з кодуванням буде використання додаткового заголовка Content-Type. Нагадаю, що завдяки ньому ми можемо вказати тип листа та для тексту та html його кодування, що нам і потрібне. Правило елементарне: кодування тексту повідомлення має збігатись з кодуванням вказаним у листі. Як дізнатись кодування тексту, яке Ви додаєте у лист? Якщо текст береться з бази даних, або генерується самим php, то скоріш за все кодування буде тим самим, що базове для системи. Для кирилычноъ Windows це cp1251 (windows-1251), для більшості сучасних Linux - utf8. Якщо ж текст береться з даних переданим користувачем, то орієнтуватись тут слід на кодування встановлене в html через тег meta. Щоб виникало менше проблем я завжди використовує теж саме кодування в html, що і у всій системі. Останнім часом це завжди UTF-8. тому заголовок листа матиме вигляд:
// To send HTML mail, the Content-type header must be set
$headers = 'MIME-Version: 1.0'."\r\n";
$headers .= 'Content-type: text/html; charset=utf8;'."\r\n";
$headers .= 'X-Mailer: PHP v.'.phpversion()."\r\n";
$headers .= 'From: '.$from."\r\n";
Однак, коли заголовок має теж бути кирилічним, то треба виконувати ще одну маніпуляцію для уникнення проблем, оскільки вказане в Content-Type кодування не розповсюджується на заголовок. Однак достатньо скористатись функцією base64_encode():
$subject = '=?utf8?B?'.base64_encode('Тема листа').'?=';
Звернніть увагу на '=?utf8?B?' - у Вас може вийти щось на зразок '=?kio8-r?B?', чи '=?windows-1251?B?' в залежності від кодування, в якому представлені дані.
Ще не кінець
Як Ви могли зрозуміти, це коротенький огляд простого способу надісилання листа з php. Далі буде складніше та для декого цікавіше. А розповім я детально про причини проблеми, яка в мене виникла з деякими поштовими сервісами та два шляхи її вирішення. Так що слідкуйте за оновленнями через RSS. Дякую всім за увагу! Вітаю зі Старим Новим Роком!Коментарі:
Шкода, що твого посту не було десь-так 2,5 роки тому, коли я його потребував ;) Тоді я знайшов відповіді на свої питання (кодування, HTML-вигляд листа), ось, тут - http://www.spravkaweb.ru/php/sovet/mail
Думаю, що сьогодні хтось може йти тим самісіньким шляхом яким колись пройшов я і мабуть ти :) Тому й вирішив почати з самого початку.
Так і буде. Одній і ті ж запитання задають з дня в день. Це нормально. Головне - це написати матеріал (відповідь на питання) простішим і легшим для засвоєння.
Я свого часу чимало прочитав вступних статей до AJAX. Читав-читав, а воно якось так складно виглядало... А тоді натрапив на "нормальну" статтю і все одразу прояснилося.



