-
-
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
whileline
Very nice snippet and works fine.