-
-
Save xeoncross/2002233 to your computer and use it in GitHub Desktop.
<?php | |
/* | |
This is a very tiny proof-of-concept SMTP client. Currently it's over 320 characters (if the var names are compressed). Think you can build one smaller? | |
*/ | |
ini_set('default_socket_timeout', 3); | |
$user = '[email protected]'; | |
$pass = ''; | |
$host = 'ssl://smtp.gmail.com'; | |
//$host = 'ssl://email-smtp.us-east-1.amazonaws.com'; //Amazon SES | |
$port = 465; | |
$to = '[email protected]'; | |
$from = '[email protected]'; | |
$template = "Subject: =?UTF-8?B?VGVzdCBFbWFpbA==?=\r\n" | |
."To: <[email protected]>\r\n" | |
."From: [email protected]\r\n" | |
."MIME-Version: 1.0\r\n" | |
."Content-Type: text/html; charset=utf-8\r\n" | |
."Content-Transfer-Encoding: base64\r\n\r\n" | |
."PGgxPlRlc3QgRW1haWw8L2gxPjxwPkhlbGxvIFRoZXJlITwvcD4=\r\n."; | |
if(smtp_mail($to, $from, $template, $user, $pass, $host, $port)) | |
{ | |
echo "Mail sent\n\n"; | |
} | |
else | |
{ | |
echo "Some error occured\n\n"; | |
} |
<?php | |
/** | |
* Connecto to an SMTP and send the given message | |
*/ | |
function smtp_mail($to, $from, $message, $user, $pass, $host, $port) | |
{ | |
if ($h = fsockopen($host, $port)) | |
{ | |
$data = array( | |
0, | |
"EHLO $host", | |
'AUTH LOGIN', | |
base64_encode($user), | |
base64_encode($pass), | |
"MAIL FROM: <$from>", | |
"RCPT TO: <$to>", | |
'DATA', | |
$message | |
); | |
foreach($data as $c) | |
{ | |
$c && fwrite($h, "$c\r\n"); | |
while(substr(fgets($h, 256), 3, 1) != ' '){} | |
} | |
fwrite($h, "QUIT\r\n"); | |
return fclose($h); | |
} | |
} |
Can I use it in my projects?
Yes, like all my code it's totally free under the MIT License.
thanks! very easy to understand. (ahm, except the foreach loop)
ini_set('default_socket_timeout', 3);
, the 3 should actually be quoted like '3'
, else PHP7 will complain about incompatible types (string vs int) in php7's strict_mode
- and it is actually supposed to be a string even in PHP5, its just that PHP5 silently convert it (as will php7 when strict_mode is disabled)
also.. this won't work by default on gmail anymore, see https://security.googleblog.com/2014/04/new-security-measures-will-affect-older.html for info.
and here's something i threw together to debug why it wasn't working on gmail...:
$user = '???';
$pass = '???';
$host = 'ssl://smtp.gmail.com';
// $host = 'ssl://email-smtp.us-east-1.amazonaws.com'; //Amazon SES
$port = 465;
$to = '???';
$from = '???';
$subject = "test";
$body = 'test<br/>test';
var_dump(smtp_mail2 ( $to, $from, $subject, $body, $user, $pass, $host, $port ));
function smtp_mail2($to, $from, $subject, $body, $user, $pass, $host, $port) {
$message = implode ( "\r\n", array (
'Subject: =?UTF-8?B?' . base64_encode ( $subject ) . '?=',
'To: <' . $to . '>',
'From: ' . $from,
'MIME-Version: 1.0',
'Content-Type: text/html; charset=utf-8',
'Content-Transfer-Encoding: base64',
"\r\n" . base64_encode ( $body ) // the (double) \r\n separate request headers from request body.
) );
$data = array (
"EHLO " . parse_url ( $host, PHP_URL_HOST ),
'AUTH LOGIN',
base64_encode ( $user ),
base64_encode ( $pass ),
"MAIL FROM: <$from>",
"RCPT TO: <$to>",
'DATA',
$message
);
// $sock = fsockopen ( $host, $port, $errno, $errstr );
$sslstuff = array (
"ssl" => array (
"verify_peer" => false,
"verify_peer_name" => false
// "cafile" => "/path/to/bundle/cacert.pem",
// "verify_peer"=> true,
// "verify_peer_name"=> true,
)
);
$socket_write_all = function ($sock, $data) {
$len = strlen ( $data );
while ( $len > 0 ) {
echo "writing...";
$written = fwrite ( $sock, $data );
if ($written === false) {
throw new RuntimeException ( 'socket_write failed. errno: ' . socket_last_error ( $sock ) . '. error: ' . socket_strerror ( socket_last_error ( $sock ) ) );
}
$len -= $written;
$data = substr ( $data, $written );
}
return; // all data written
};
$sock = stream_socket_client ( $host . ':' . $port, $errno, $errstr, 10, STREAM_CLIENT_CONNECT, stream_context_create ( $sslstuff ) );
if (false === $sock) {
throw new \RuntimeException ( 'failed to connect! errno: ' . $errno . '. errstr: ' . $errstr );
}
$debugMessageLog = array ();
stream_set_blocking ( $sock, true );
$welcomeMessage = fgets ( $sock );
$debugMessageLog [] = array (
'connect',
$welcomeMessage
);
// var_dump ( $welcomeMessage );
foreach ( $data as $message ) {
$socket_write_all ( $sock, $message . "\r\n" );
$tmpFullResponse = '';
while ( false !== ($tmpResponse = fgets ( $sock )) ) {
var_dump ( $tmpResponse );
$tmpFullResponse .= $tmpResponse;
}
$debugMessageLog [] = array (
$message,
$tmpFullResponse
);
unset ( $tmpFullResponse, $tmpResponse, $message );
}
$socket_write_all ( $sock, "QUIT\r\n" );
var_dump ( $debugMessageLog );
return fclose ( $sock );
}
Really neat code golf here, but do not use this in production.
- Requires pre-quoted mailboxes
- No dot stuffing on message content
- Possible infinite loop on the
while
line
Very nice snippet and works fine.