I needed a quick ‘n dirty script to test outgoing SMTP email via PHP and found php-smtp. Pasting it here in case the repo ever disappears: <?php namespace Snipworks\Smtp; /** * Send email class using SMTP Authentication * * @class Email * @package Snipworks\SMTP */ class Email { const CRLF = "\r\n"; const TLS = 'tcp'; const SSL = 'ssl'; const OK = 250; /** @var string $server */ protected $server; /** @var string $hostname */ protected $hostname; /** @var int $port */ protected $port; /** @var resource $socket */ protected $socket; /** @var string $username */ protected $username; /** @var string $password */ protected $password; /** @var int $connectionTimeout */ protected $connectionTimeout; /** @var int $responseTimeout */ protected $responseTimeout; /** @var string $subject */ protected $subject; /** @var array $to */ protected $to = array(); /** @var array $cc */ protected $cc = array(); /** @var array $bcc */ protected $bcc = array(); /** @var array $from */ protected $from = array(); /** @var array $replyTo */ protected $replyTo = array(); /** @var array $attachments */ protected $attachments = array(); /** @var string|null $protocol */ protected $protocol = null; /** @var string|null $textMessage */ protected $textMessage = null; /** @var string|null $htmlMessage */ protected $htmlMessage = null; /** @var bool $isHTML */ protected $isHTML = false; /** @var bool $isTLS */ protected $isTLS = false; /** @var array $logs */ protected $logs = array(); /** @var string $charset */ protected $charset = 'utf-8'; /** @var array $headers */ protected $headers = array(); /** * Class constructor * -- Set server name, port and timeout values * * @param string $server * @param int $port * @param int $connectionTimeout * @param int $responseTimeout * @param string|null $hostname */ public function __construct($server, $port = 25, $connectionTimeout = 30, $responseTimeout = 8, $hostname = null) { $this->port = $port; $this->server = $server; $this->connectionTimeout = $connectionTimeout; $this->responseTimeout = $responseTimeout; $this->hostname = empty($hostname) ? gethostname() : $hostname; $this->setHeader('X-Mailer', 'PHP/' . phpversion()); $this->setHeader('MIME-Version', '1.0'); } /** * @param string $key * @param mixed|null $value * @return Email */ public function setHeader($key, $value = null) { $this->headers[$key] = $value; return $this; } /** * Add to recipient email address * * @param string $address * @param string|null $name * @return Email */ public function addTo($address, $name = null) { $this->to[] = array($address, $name); return $this; } /** * Add carbon copy email address * * @param string $address * @param string|null $name * @return Email */ public function addCc($address, $name = null) { $this->cc[] = array($address, $name); return $this; } /** * Add blind carbon copy email address * * @param string $address * @param string|null $name * @return Email */ public function addBcc($address, $name = null) { $this->bcc[] = array($address, $name); return $this; } /** * Add email reply to address * * @param string $address * @param string|null $name * @return Email */ public function addReplyTo($address, $name = null) { $this->replyTo[] = array($address, $name); return $this; } /** * Add file attachment * * @param string $attachment * @return Email */ public function addAttachment($attachment) { if (file_exists($attachment)) { $this->attachments[] = $attachment; } return $this; } /** * Set SMTP Login authentication * * @param string $username * @param string $password * @return Email */ public function setLogin($username, $password) { $this->username = $username; $this->password = $password; return $this; } /** * Get message character set * * @param string $charset * @return Email */ public function setCharset($charset) { $this->charset = $charset; return $this; } /** * Set SMTP Server protocol * -- default value is null (no secure protocol) * * @param string $protocol * @return Email */ public function setProtocol($protocol = null) { if ($protocol === self::TLS) { $this->isTLS = true; } $this->protocol = $protocol; return $this; } /** * Set from email address and/or name * * @param string $address * @param string|null $name * @return Email */ public function setFrom($address, $name = null) { $this->from = array($address, $name); return $this; } /** * Set email subject string * * @param string $subject * @return Email */ public function setSubject($subject) { $this->subject = $subject; return $this; } /** * Set plain text message body * * @param string $message * @return Email */ public function setTextMessage($message) { $this->textMessage = $message; return $this; } /** * Set html message body * * @param string $message * @return Email */ public function setHtmlMessage($message) { $this->htmlMessage = $message; return $this; } /** * Get log array * -- contains commands and responses from SMTP server * * @return array */ public function getLogs() { return $this->logs; } /** * Send email to recipient via mail server * * @return bool */ public function send() { $message = null; $this->socket = fsockopen( $this->getServer(), $this->port, $errorNumber, $errorMessage, $this->connectionTimeout ); if (empty($this->socket)) { return false; } $this->logs['CONNECTION'] = $this->getResponse(); $this->logs['HELLO'][1] = $this->sendCommand('EHLO ' . $this->hostname); if ($this->isTLS) { $this->logs['STARTTLS'] = $this->sendCommand('STARTTLS'); stream_socket_enable_crypto($this->socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT); $this->logs['HELLO'][2] = $this->sendCommand('EHLO ' . $this->hostname); } $this->logs['AUTH'] = $this->sendCommand('AUTH LOGIN'); $this->logs['USERNAME'] = $this->sendCommand(base64_encode($this->username)); $this->logs['PASSWORD'] = $this->sendCommand(base64_encode($this->password)); $this->logs['MAIL_FROM'] = $this->sendCommand('MAIL FROM: <' . $this->from[0] . '>'); $recipients = array_merge($this->to, $this->cc, $this->bcc); foreach ($recipients as $address) { $this->logs['RECIPIENTS'][] = $this->sendCommand('RCPT TO: <' . $address[0] . '>'); } $this->setHeader('Date', date('r')); $this->setHeader('Subject', $this->subject); $this->setHeader('From', $this->formatAddress($this->from)); $this->setHeader('Return-Path', $this->formatAddress($this->from)); $this->setHeader('To', $this->formatAddressList($this->to)); if (!empty($this->replyTo)) { $this->setHeader('Reply-To', $this->formatAddressList($this->replyTo)); } if (!empty($this->cc)) { $this->setHeader('Cc', $this->formatAddressList($this->cc)); } if (!empty($this->bcc)) { $this->setHeader('Bcc', $this->formatAddressList($this->bcc)); } $boundary = md5(uniqid(microtime(true), true)); $this->setHeader('Content-Type', 'multipart/mixed; boundary="mixed-' . $boundary . '"'); if (!empty($this->attachments)) { $this->headers['Content-Type'] = 'multipart/mixed; boundary="mixed-' . $boundary . '"'; $message .= '--mixed-' . $boundary . self::CRLF; $message .= 'Content-Type: multipart/alternative; boundary="alt-' . $boundary . '"' . self::CRLF . self::CRLF; } else { $this->headers['Content-Type'] = 'multipart/alternative; boundary="alt-' . $boundary . '"'; } if (!empty($this->textMessage)) { $message .= '--alt-' . $boundary . self::CRLF; $message .= 'Content-Type: text/plain; charset=' . $this->charset . self::CRLF; $message .= 'Content-Transfer-Encoding: base64' . self::CRLF . self::CRLF; $message .= chunk_split(base64_encode($this->textMessage)) . self::CRLF; } if (!empty($this->htmlMessage)) { $message .= '--alt-' . $boundary . self::CRLF; $message .= 'Content-Type: text/html; charset=' . $this->charset . self::CRLF; $message .= 'Content-Transfer-Encoding: base64' . self::CRLF . self::CRLF; $message .= chunk_split(base64_encode($this->htmlMessage)) . self::CRLF; } $message .= '--alt-' . $boundary . '--' . self::CRLF . self::CRLF; if (!empty($this->attachments)) { foreach ($this->attachments as $attachment) { $filename = pathinfo($attachment, PATHINFO_BASENAME); $contents = file_get_contents($attachment); $type = mime_content_type($attachment); if (!$type) { $type = 'application/octet-stream'; } $message .= '--mixed-' . $boundary . self::CRLF; $message .= 'Content-Type: ' . $type . '; name="' . $filename . '"' . self::CRLF; $message .= 'Content-Disposition: attachment; filename="' . $filename . '"' . self::CRLF; $message .= 'Content-Transfer-Encoding: base64' . self::CRLF . self::CRLF; $message .= chunk_split(base64_encode($contents)) . self::CRLF; } $message .= '--mixed-' . $boundary . '--'; } $headers = ''; foreach ($this->headers as $k => $v) { $headers .= $k . ': ' . $v . self::CRLF; } $this->logs['MESSAGE'] = $message; $this->logs['HEADERS'] = $headers; $this->logs['DATA'][1] = $this->sendCommand('DATA'); $this->logs['DATA'][2] = $this->sendCommand($headers . self::CRLF . $message . self::CRLF . '.'); $this->logs['QUIT'] = $this->sendCommand('QUIT'); fclose($this->socket); return substr($this->logs['DATA'][2], 0, 3) == self::OK; } /** * Get server url * -- if set SMTP protocol then prepend it to server * * @return string */ protected function getServer() { return ($this->protocol) ? $this->protocol . '://' . $this->server : $this->server; } /** * Get Mail Server response * @return string */ protected function getResponse() { $response = ''; stream_set_timeout($this->socket, $this->responseTimeout); while (($line = fgets($this->socket, 515)) !== false) { $response .= trim($line) . "\n"; if (substr($line, 3, 1) == ' ') { break; } } return trim($response); } /** * Send command to mail server * * @param string $command * @return string */ protected function sendCommand($command) { fputs($this->socket, $command . self::CRLF); return $this->getResponse(); } /** * Format email address (with name) * * @param array $address * @return string */ protected function formatAddress($address) { return (empty($address[1])) ? $address[0] : '"' . addslashes($address[1]) . '" <' . $address[0] . '>'; } /** * Format email address to list * * @param array $addresses * @return string */ protected function formatAddressList(array $addresses) { $data = array(); foreach ($addresses as $address) { $data[] = $this->formatAddress($address); } return implode(', ', $data); } } use Snipworks\Smtp\Email; $mail = new Email('server.example.com', 587); $mail->setProtocol(Email::TLS) ->setLogin('sender@example.com', 'SECRET') ->setFrom('sender@example.com') ->setSubject('Test subject') ->setTextMessage('Plain text message') ->setHtmlMessage('<strong>HTML Text Message</strong>') ->addTo('recipient@example.com'); if ($mail->send()) { echo 'SMTP Email has been sent' . PHP_EOL; exit(0); } echo 'An error has occurred. Please check the logs below:' . PHP_EOL; print_r($mail->getLogs());