PHPコーディング

SMTPソケットをオープンしてメール送信(ソケットオープン)

2010年01月20日
PHPからメールを送信するには色々な方法があります。

手っ取り早く日本語メールを送信するには【mb_send_mail】があります。
添付ファイルやhtmlメールを送信するには、【mail】を使ってヘッダなど書かけば可能です。
しかし、この【mail】関数、いちいちSMTPソケットを開いたり閉じたりするので、メールマガジン、ステップメールを配信するのには不向きのようです。
その上、sendmailやqmailなどがインストールされていて、PHPから使えないとメールが送信できないそうです。
更に更に、処理が重たいのです。

ソケットのオープン・クローズも制御するには直接ソケットをオープンしてメールを送信しなければいけないようです。

もちろんその辺りの無料のツールも出回ってます。有名どころではPEAR::Mail_Mime

利用してもいいのですが、なにかあったとき自分でちゃっちゃと直せないと困るので、自分で書いてみることにしました。

大まかな流れは、
1. ソケットオープン
2. メール送信
3. ソケットクローズ
です。

メールマガジンやステップメール配信の場合は2を繰り返します。

まずはソケットオープンです。

$smtp = "smtp.domain.xxx";
$port = 587;
メール送信時にも認証が必要になってから、ポート番号は587のことが多くなってます。
$id = "mail_id";
$pw = "smtp_pw";

$sock = @fsockopen($smtp, $port);
でオープンできます。

成功したら、
@fputs($sock, "EHLO ".$port."\r\n");
認証が必要になってからコマンドはEHLO。

ここでサーバーが色々な情報を返してきます。
そのうちの1つが、利用可能な認証方式。
250-AUTH PLAIN LOGIN DIGEST-MD5 CRAM-MD5 NTLM
の形式で返ってきます。

利用できる認証方式は、PLAIN、LOGIN、DIGEST-MD5、CRAM-MD5、NTLM。
それぞれの認証方式は後にして、ここで問題が発生です。

while (!feof($sock)) {
  $result = @fgets($sock, 128);
  $num = preg_match("/^250-AUTH /i", $result);
  if(0 < $num){
    $login_method = str_replace("250-AUTH ", "", $result);
  }
}
として、サーバーから返された文字列を取得しようとしたのですが、どうやら無限ループに陥っているようで、タイムアウトになってしまいます。

調べていくと、【feof($sock)】でfalseが返ってきていないようです。【fsockopen】でオープンしたストリームでも使えるのに・・・なぜ?PHPのバグ??それとも終了しないとeofが返ってこないのか???

仕方ないので、別の方法に切替です。

while ($result = @fgets($sock, 128)) {
  $num = preg_match("/^250-AUTH /i", $result);
  if(0 < $num){
    $login_method = str_replace("250-AUTH ", "", $result);
  }
}
で一応解決です。
でも、ものすごく時間がかかってしまいます。
時間がかかっているのは、【$result = @fgets($sock, 128)】の部分です。
文字列が返ってくる場合は早いのですが、falseが返ってくるのに時間がかかっています。

PHPのマニュアルを読むと、【feof】関数はタイムアウトになったときもfalseを返すとのこと。

そこで、タイムアウトまでの時間を短くし、処理時間の短縮を試みました。

【stream_set_timeout】でタイムアウトまでの時間を設定できます。
タイムアウトになったら【stream_get_meta_data】で値が取得できます。

stream_set_timeout ($sock, 5);    //タイムアウトまでの時間を5秒に設定
while (!feof($sock)) {
  $result = @fgets($sock, 128);
  $info = stream_get_meta_data($sock);
  if($info['timed_out'] == true){  //タイムアウトになったらこの値がtrueになる
    break;
  }
  $num = preg_match("/^250-AUTH /i", $result);
  if(0 < $num){
    $login_method = str_replace("250-AUTH ", "", $result);
  }
}

5秒ではなくもっと小さな値にすればもっと早くなります。

これで解決!のようです。動かしているうちまた不都合が見つかるかもしれませんが。

長くなったので、smtp認証はまた次回。
コメントの書き込み
コメント
2018年10月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
先月
来月
カテゴリ
検索
関連サイト
プロフィール
【ネットネーム】
みゅー

キャラクター by ツカエルサイト


【趣味】
・プログラミング
・写真
・楽器演奏
・手芸
・日曜大工
・家の中の不便を便利に
・考える
・自然科学
・猫と戯れる
・ジグソーパズル

【仕事】
・派遣社員でSE・PGやっていました。次の良い仕事がみつからないので、ビジネスへ注力しようと思っています。
・経験言語:VB6、VB.NET、PHP、Perl、JAVA、Oracle、SQLServer、PostgreSQL



【名前】
アン(足)

2014年4月22日生まれ 女の子
あだ名は くノ一
普段は普通にしゃべりますが、興奮すると『ニャ』を連発します

【趣味】
・狩
・ご飯を食べる
・ママのお手伝い

【仕事】
ママのビジネスの看板招き猫
ママの代わりにPC入力
仕事中のママの右腕を温める
ママに心配をかける
いろんな事をしでかしてママを退屈させない

RSSフィード
コメント
パトカーってハチワレ
2018-10-15 16:15:11
パトカーってハチワレ
2018-10-15 16:12:42
Tweet