Статьи

Отправка писем с помощью PHP

Мы знаем, почему вы здесь … вы хотите написать скрипт для отправки электронных писем своим друзьям с забавными адресами возврата. Я здесь, чтобы сказать тебе, что ты лучше этого. Ты можешь сделать намного больше со своей жизнью! Но какие еще причины вы могли бы иметь?

Ну, может быть, у вас есть задание cron, о котором вы хотите сообщить о проблемах, есть пользовательский сценарий, о котором вы хотели бы получать уведомления при запуске, есть форма «Свяжитесь с нами», которая пересылает вам сообщения, вы хотите сгибать свои Нужно настроить PHP-скрипт подтверждения по электронной почте — есть множество других причин для отправки электронной почты с помощью PHP. Плюс, это так просто!

В большинстве случаев ваша установка PHP сможет отправлять электронные письма. Если вы используете общий хост или если вы установили PHP с использованием системы управления пакетами, такой как apt-get, то, скорее всего, все готово. Вам действительно нужно беспокоиться о дополнительной конфигурации, только если вы компилируете PHP из исходного кода или запускаете его в Windows. В любом случае, есть много ресурсов, доступных онлайн, чтобы помочь вам. Поскольку это выходит за рамки этой статьи, я предполагаю, что вы настроены. Если нет, Google будет вашим другом.

Супер базовый пример

Чтобы отправить просто простое электронное письмо, используйте следующий код:

<?php mail($address, $subject, $message); 

На самом деле, это все, что нужно для отправки простых текстовых писем (если у вас это не сработает, снова обратитесь в Google, чтобы узнать, как правильно настроить PHP).

Теперь посмотрим, как это будет выглядеть в скрипте. Допустим, например, что вы хотите, чтобы скрипт отправлял вам электронное письмо каждый раз при сбое запроса:

 <?php $query = "SELECT left_arm AS arm_in, right_leg AS leg_in, front_head AS head_in FROM hokey_pokey WHERE its_about = 'all'"; try { $result = $db->query($query); // ... } catch (PDOException $e) { mail("bad_things@my_database.com", "Error in " . $_SERVER["SCRIPT_NAME"], $e->getMessage()); } 

Если при выполнении вашего запроса произошла непредвиденная ошибка, вы получите электронное письмо с информацией о том, в каком скрипте произошла ошибка и что это за ошибка.

Полноценный пример HTML-почты

Теперь давайте посмотрим на полноценный пример multipart mail() который имеет тело HTML с альтернативой в виде простого текста и вложенный файл:

 <?php $emailList = array("[email protected]", "[email protected]", "[email protected]", "[email protected]"); $headers = "From: "Fluffy Mumsy" <[email protected]>rn" . "Reply-To: [email protected]" . "MIME-Version: 1.0rn" . "Content-Type: multipart/mixed; boundary="YaGottaKeepEmSeparated"rn"; $subject = "Please donate all your moneys to us"; $goodAttachment = chunk_split(base64_encode(file_get_contents( "novyrus.zip"))); $body = "--YaGottaKeepEmSeparatedrn" . "Content-Type: multipart/alternative; boundary="EachEmailAlternative"rn" . "--EachEmailAlternativern" . "Content-Type: text/plain; charset="iso-8859-1"rn" . "Content-Transfer-Encoding: 7bitrn" . "You have cheap text email you have no money. Please ignore.rn" . "--EachEmailAlternativern" . "Content-Type: text/html; charset="iso-8859-1"rn" . "<html> <head> <title>We need money to give you</title> </head> <body> <p>We found some <span style='color:green'>money</span>. And we need you give us money to give some you. We is good people. You can trust. Please install contact information attachment</p> </body> </html>rn" . "--YaGottaKeepEmSeparatedrn" . "Content-Type: application/zip; name="novyrus.zip"rn" . "Content-Transfer-Encoding: base64rn" . "Content-Disposition: attachmentrn" . $goodAttachment . "rn" . "--YaGottaKeepEmSeparated--"; foreach ($emailList AS $addy) { $success = mail($addy, $subject, $body, $headers); if (!$success) { echo "Mail to " . $addy . " is fail."; } } 

Некоторые аспекты более типичных почтовых сценариев были упрощены, чтобы облегчить понимание общей концепции, хотя я коснусь этих в этой разбивке.

Во-первых, массив $emailList содержит несколько адресов электронной почты, с $emailList я хотел бы поделиться своим сообщением. Массив повторяется в конце скрипта, и на каждый адрес будет отправлена ​​копия моего письма.

Далее строка $headers создается с различными заголовками почты. Каждый заголовок в строке разделен с CRLF ( rn ) согласно RFC 2822 , стандарту, который определяет формат сообщений электронной почты.

"From: "Fluffy Mumsy" <[email protected]>rn"
В заголовке From указывается адрес электронной почты, с которого получатель увидит сообщение как полученное.

"Reply-To: [email protected]"
Заголовок Reply-To — это адрес электронной почты, на который должен быть отправлен ответ. Если сделать его отличным от заголовка «From:», то вероятность того, что это письмо будет идентифицировано как спам, возрастает (хотя, если бы это было единственное, что заставило почтовый клиент поднять красный флаг, это сообщение было спамом, то, вероятно, оно бы прошло ).

"MIME-Version: 1.0rn"
Заголовок MIME-версии сообщает серверу ожидать многоцелевых расширений Интернет-почты в теле, что позволяет вам иметь более сложную электронную почту, чем простой текст.

"Content-Type: multipart/mixed; boundary="YaGottaKeepEmSeparated"rn"
Заголовок «Content-Type» на самом деле делает две вещи: он указывает, что в теле будут различные части, и определяет, какая строка используется для разделения каждой части. Эта граничная строка не может появиться где-либо еще в электронном письме, иначе почтовый клиент не сможет правильно проанализировать сообщение. Например, вы можете использовать «12» в качестве границы, хотя есть вероятность, что она появится в другом месте сообщения. Я выбрал «YaGottaKeepEmSeparated». Большинство людей назначают случайно сгенерированный хеш в качестве границы, например, $boundary = md5(time()) , поскольку вероятность столкновения очень мала.

Содержимое novyrus.zip , который здесь находится в том же каталоге, что и скрипт, кодируется в base64 и разбивается на «куски» для облегчения переваривания почтовым клиентом. Результат сохраняется в $goodAttachment который появится позже.

Наконец, тело сообщения электронной почты состоит из …

"--YaGottaKeepEmSeparatedrn"
Это первый случай использования границы, определенной ранее, и он говорит почтовому клиенту: «эй, вот начало первого раздела почтового сообщения», и он всегда начинается с двойной черты перед выбранной границей. строка.

"Content-Type: multipart/alternative; boundary="EachEmailAlternative"rn"
Помимо «multipart / mixed», указанного в заголовках письма, вы также можете использовать заголовок Content-Type с «multipart / alternative» внутри тела и с другой границей, характерной для этой разбивки, чтобы обеспечить альтернативные форматы для сообщения.

"--EachEmailAlternativern"
Это первый экземпляр вложенной границы и запускается первая альтернативная версия сообщения.

"Content-Type: text/plain; charset="iso-8859-1"rn"
Этот заголовок Content-Type сообщает почтовому клиенту, что альтернативой является простой текст. Если клиент не способен отображать более сложные форматы, такие как HTML, он будет использовать эту версию сообщения.

"Content-Transfer-Encoding: 7bitrn"
Заголовок Content-Transfer-Encoding указывает схему кодирования, используемую в сообщении. По историческим причинам «7bit» является значением по умолчанию, поэтому его можно не указывать. Я включил это так просто, чтобы вы знали об этом.

"You have cheap text email you have no money. Please ignore.rn"
Это текстовая версия сообщения, которую увидят пользователи, не использующие HTML.

"--EachEmailAlternativern"
Конец первой альтернативы достигнут, и вы готовы запустить следующую альтернативную версию.

"Content-Type: text/html; charset="iso-8859-1"rn"
Этот заголовок Content-Type сообщает клиенту, что эта версия отформатирована как HTML, и набор символов, который используется.

"<html> ... </html>rn"
Обратите внимание, что эта версия, помимо включения тегов HTML, имеет содержимое, которое значительно отличается от версии в виде простого текста. Некоторые спам-фильтры могут рассматривать это как еще одну причину, чтобы блокировать мне сообщение от попадания во входящие.

"--YaGottaKeepEmSeparatedrn"
Это многослойная / смешанная граница, указывающая, что вы достигли конца раздела тела сообщения со всеми его альтернативами.

"Content-Type: application/zip; name="novyrus.zip"rn"
Заголовок Content-Type указывает на то, что следующая часть письма является вложением (файл novyrus.zip ) и является ZIP-файлом.

"Content-Transfer-Encoding: base64rn"
7-битное кодирование ограничивает символы семью битами и может не в состоянии точно представить все необходимые двоичные символы для файла ZIP, поэтому файл был закодирован в формате base64 и разделен на части. Заголовок Content-Transfer-Encoding здесь позволяет клиенту знать, как декодировать файл вложения.

"Content-Disposition: attachmentrn"
Заголовок Content-Disposition подробно описывает, как должен быть представлен контент; Есть два возможных значения: вложение и встроенный . Хотя показывать встроенный элемент ZIP-файла в сообщении вряд ли имеет смысл, он удобен для встраивания изображений.

$goodAttachment . "rn"
Содержимое вложенного файла просто сбрасывается в микс.

"--YaGottaKeepEmSeparated--"
Это последняя граница, заявляющая, что больше ничего не должно следовать, заканчиваясь одним последним набором двойных штрихов.

Резюме

Вот оно! Вы видели, как отправлять сверхосновные текстовые сообщения электронной почты и полноценные HTML-письма с вложениями. Простые электронные письма — это просто вызов функции mail (). Для сообщений HTML вам необходимо разбить свою электронную почту на сегменты, используя стандарты MIME, разделенные границей по вашему выбору. Затем вы определяете, что такое контент, как он кодируется, возможно, расположение, а затем сам контент. В зависимости от того, кого вы планируете отправлять по электронной почте, вам следует проявлять осмотрительность в отношении факторов, которые могут привести к тому, что ваше сообщение будет с большей вероятностью помечено как спам, на тот случай, если вы действительно захотите отправить что-то серьезное.

Изображение через Photosani / Shutterstock