ホームページ php教程 php手册 PHP で Socket を使用して電子メールを送信する

PHP で Socket を使用して電子メールを送信する

Jun 21, 2016 am 09:06 AM
gt message nbsp smtp this

筆者が申請したいくつかの PHP ホームページ スペースの中で、メール機能を提供できるものは多くありません。 mail() 関数を呼び出した後は、常に何もする必要がありません。しかし、オンライン生活において電子メールの役割はますます高まっています。考えてみてください。電子メールを受信せずにインターネットをサーフィンする場合、インターネットのバグは本当のインターネットのバグと言えるでしょうか?電子メールの役割についてはこれ以上話したくないのですが、ホームページ スペースが mail() の送信をサポートしていない場合はどうすればよいでしょうか?ソケット経由でメールを送信することも考えましたが、残念ながら私は PHP を使用したソケット プログラミングに慣れていません。また、メールを送信するには SMTP プロトコルが必要で、大量の英語を読む必要があるため、勉強したことがありません。ついにある日、ソケット プログラミングを使用して電子メールを送信することに関する記事を見つけました。私は宝物を見つけたかのようにそれをコピーし、誰でも使用できる PHP で利用できるクラスに変換しました。元の記事は単なるサンプルであり、いくつかのエラーがありましたが、多くの実験と変更を経て、最終的には MIME を組み合わせて送信するという前の手順に従って、ソケットを直接使用して指定されたメールボックスにメールを送信するクラスに変更しました。この記事では、mail() 関数をサポートしていない Web サイトでも電子メールを送信できます。メール送信の処理には時間がかかるため、mail() の処理機構と全く同じではないため、速度は遅くなりますが、同時にメールを送信するという緊急のニーズを解決することもできます。ソケット プログラミングに PHP を使用する方法を学びます。次に、このクラスの実装原理を紹介し、同時に SMTP に関する基礎知識を説明します。

ソケット プログラミングの概要
私は TCP/IP プログラミングの専門家ではないので、ここでは私の理解と経験を共有しているだけであることを皆さんにお伝えしたいと思います。

fsockopen 関数を使用してインターネット接続を開きます。関数の構文形式は次のとおりです。

int fsockopen(string hostname, int port, int [errno], string [errstr], int [timeout]);パラメータの意味を説明する必要はないと思います。はい、ここでは SMTP プロトコルが使用されているため、ポート番号は 25 です。接続が正常に開かれると、ファイル ハンドルのように使用できるソケット ハンドルが返されます。利用可能な操作には、fputs()、fgets()、feof()、fclose()
などが含まれます。

とても簡単な紹介は以上です。

SMTPの基本
TCP/IPをベースとしたインターネットプロトコルの一般的なコマンド形式は、リクエスト/レスポンス方式で実装されており、すべてテキスト情報が使用されるため、処理が容易です。 SMTP は Simple Mail Transfer Protocol の略称で、クライアントがサーバーに電子メールを送信できるようにします。したがって、以下で説明するコマンドは、クライアントがサーバーに要求命令を送信することを指し、応答はサーバーからクライアントに返される情報を指します。

SMTPはコマンドヘッダーとメッセージボディの2つの部分に分かれています。コマンドヘッダーは主にクライアントとサーバー間の接続、検証などを完了します。プロセス全体は複数のコマンドで構成されます。各コマンドがサーバーに送信されると、サーバーは応答情報 (通常は 3 桁の応答コードと応答テキスト) を返します。さまざまなサーバーから返される応答コードはプロトコルに準拠していますが、応答テキストはプロトコルに準拠していません。各コマンドと応答の最後にはキャリッジ リターン文字があるため、コマンドと応答は fputs() と fgets() を使用して処理できます。 SMTP コマンドと応答メッセージは 1 行です。メッセージ本文は電子メールの本文であり、最後の終了行は別の「.」で終わる必要があります。

クライアントで一般的に使用される SMTP コマンドは次のとおりです:

HELO hostname: サーバーに挨拶し、使用されているマシン名をクライアントに伝えます。気軽に入力できます
MAIL FROM: sender_id: サーバーに送信者のアドレスを伝えます
RCPT TO:receiver_id:サーバーの受信者のアドレスを伝えます
DATA:レターの内容は以下で送信され始め、それはのみを含む特別な行で終わる必要があります。
RESET:前のコマンドをキャンセルして最初から開始します
VERIFY userid: アカウントが存在するかどうかを確認します (このコマンドはオプションです)。サーバーがサポートしていない可能性があります)
QUIT: 接続を終了し、終了します
サーバーから返される応答情報は (形式: 応答コード + スペース + 説明) です):

220 サービス準備完了 (ソケット接続が成功するとこの情報が返されます)
221 処理中です
250 リクエスト電子メールアクションは正しく完了しています (この情報は、HELO、MAIL FROM、RCPT TO が成功した場合に返されます) 、QUIT コマンドが正常に実行されました)
354 データの送信を開始し、で終了します (DATA コマンドが正常に実行された場合、この情報が返されます。顧客端末は情報を送信するはずです)
500 構文エラー、コマンドが認識できません
550コマンドを実行できません。メールボックスが無効です
552 割り込み処理: ユーザーがファイル領域を超えています
簡単なコマンド ヘッダーを以下に示します (これはソケットを開いた後に行われます)。これは、stmp に電子メールを送信したテスト結果です。 .263.net:

HELO limodou
250 smtp.263.net
MAIL FROM:
chatme@263.net

250 OK RCPT TO: chatme@263.net

250 OK DATA3 54 エンドデータ
宛先:
chatme@263.net

差出人: chatme@263.net
件名: test差出人: chatme@263.net

test OK: C46411 としてキューに追加されました。 C5097E0
SMTPに関する簡単な知識です。関連コンテンツは RFC にあります。

RFC 821 では、電子メールの送受信に関する関連手順が定義されています。
RFC 822 は電子メールのコンテンツの形式を指定します。
RFC 2045-2048 はマルチメディア電子メール コンテンツの形式を策定し、
RFC 1113、1422-1424 は電子メールの機密性を向上させる方法について説明します。

send_mailクラスの実装
今回は私が作成したsend mailクラスを紹介します。上記の準備知識を踏まえて、以下のように実装していきます。

クラスのメンバー変数

var $lastmessage; //返された最後の応答メッセージを記録します
var $debug;使用する 使用する 使用する 使用する 使用する 使用する'sを通して - - - - - - - - - - - - $ lastmessageと$ lastActは、最後のA応答メッセージを記録するために使用され、エラーが発生したときにユーザーが使用できるコマンドを実行しました。テストの必要があるため、$debug 変数も定義しました。その値が true の場合、プロセスの実行中にいくつかの実行情報が表示されます。それ以外の場合は、出力はありません。 $fp は、開いたソケット ハンドルを保存するために使用されます。

クラスの構築


------------------------------------------ --- --------------------------------------
function send_mail($smtp, $welcome="" .
$this->welcome=gethostbyaddr("localhost");
$this->lastmessage=" ";
$this->lastact="";
$this-> - ------------------------------------------------- - -------
このコンストラクターは主にいくつかの初期値の決定と設定を完了します。 $welcome は、サーバーにユーザー名を伝えるために HELO ディレクティブで使用されます。 HELO 命令にはマシン名が必要ですが、マシン名がなくても使用できます。ユーザーが $welcome を指定しない場合、ローカル マシン名が自動的に検索されます。

デバッグ情報を表示

------------------------------------------ -- --------------------------------------
1 function show_debug($message, $inout)
2 {
3 if ($this->debug)
4 if($inout=="in") //応答情報
6 {
7 $m='<< '; }
" ";
13 $message=nl2br( $message);
14 echo "${m}${message}";
15 }
16 }
------------ -------------------------------------- ------------ ------------------
この関数はデバッグ情報を表示するために使用されます。 $inout には、アップロード命令であるか返される応答であるかを指定できます。アップロード命令である場合は "out" を使用し、返される応答である場合は "in" を使用します。

3行目はデバッグ情報を出力するかどうかを決定します。
5 行目で、応答メッセージであるかどうかを判断し、そうでない場合は 7 行目の情報の前に「>>」を追加します。アップロードの指示。
11-12行目、最後の情報文字列が改行文字かどうかを判断し、そうでない場合はHTML改行マークを追加します。 13 行目は、すべての改行文字を HTML 改行タグに変換します。
14 行目、メッセージ全体を出力し、違いを示すためにメッセージの色をグレーに設定します。コマンドを実行します

-------------------------------------- --- ----------------------------------
1    function do_command($command, $code)
2    {
3        $this->lastact=$command;
4        $this->show_debug($this->lastact, "out");
5        fputs ( $this->fp, $this->lastact );
6        $this->lastmessage = fgets ( $this->fp, 512 );
7        $this->show_debug($this->lastmessage, "in");
8        if(!ereg("^$code", $this->lastmessage))
9        {
10            return false;
11        }
12        else
13            return true;
14    }
--------------------------------------------------------------------------------
  在编写socket处理部分发现,一些命令的处理很相似,如HELO,MAIL FROM,RCPT TO,QUIT,DATA命令,都要求根据是否显示调试信息将相关内容显示出来,同时对于返回的响应码,如果是期望的,则应继续处理,如果不是期望的,则应中断出理。所以为了清晰与简化,专门对这些命令的处理编写了一个通用处理函数。函数的参数中$code为期望的响应码,如果响应码与之相同则表示处理成功,否则出错。

第3行,记录最后执行命令。
第4行,将上传命令显示出来。
第5行,则使用fputs真正向服务器传换指令。
第6行,从服务器接收响应信息将放在最后响应消息变量中。
第7行,将响应信息显示出来。
第8行,判断响应信息是否期待的,如果是则第13行返回成功(true),否则在第10行返回失败(false)。

  这样,这个函数一方面完成指令及信息的发送显示功能,别一方面对返回的响应判断是否成功。

メール送信処理

以下が本当の秘密ですが、よく見てください。 :)

---------------------------------------------- --- ----------------------------------
1 関数 send( $to,$from,$subject ,$message )
2 {
3
4 //サーバーに接続します
5 $this->lastact="connect";
6
7 $this->show_debug("SMTP サーバーに接続します : ".$this ->smtp . set_socket_blocking( $this->fp, true );
13 $this->lastmessage=fgets($this->fp,512);
14 $this->show_debug($this- >lastmessage, " in");
15
16 if (! ereg ( "^220", $this->lastmessage ) )
17 {
18 return false;
19 }
2 1 lastact="HELO " $this->ようこそ。"n";
23 ($this ->fp);
26 「」 if(!$this->do_command($ this->lastact, " 250"))
31 }
35
36 to" . "n";
37 if(!$this->do_command($this->lastact, "250"))
38 {
39 ;
40 false を返します ;
41 If(!$this->do_command($this->lalastact, "354" ))
46 1 $件名) && !例($head, $message))
54
58                //处理From头
59                $head="From: $from\n";
60                if(!empty($from) && !ereg($head, $message))
61                {
62                    $message = $head.$message;
63                }
64
65                //处理To头
66                $head="To: $to\n";
67                if(!empty($to) && !ereg($head, $message))
68                {
69                    $message = $head.$message;
70                }
71
72                //加上结束串
73                if(!ereg("\n\.\n", $message))
74                    $message .= "\n.\n";
75                $this->show_debug($message, "out");
76                fputs($this->fp, $message);
77
78                $this->lastact="QUIT\n";
79                if(!$this->do_command($this->lastact, "250"))
80                {
81                    fclose($this->fp);
82                    return false;
83                }
84            }
85            return true;
86        }
87        else
88        {
89            $this->show_debug("Connect failed!", "in");
90            return false;
91        }
92    }
--------------------------------------------------------------------------------
  有些意思很清楚的我就不说了。

  这个函数一共有四个参数,分别是$to表示收信人,$from表示发信人,$subject表求邮件主题和$message表示邮件体。如果处理成功则返回true,失败则返回false。

第8行,连接邮件服务器,如果成功响应码应为220。
第12行,设置阻塞模式,表示信息必须返回才能继续。详细说明看手册吧。
第16行,判断响应码是否为220,如果是,则继续处理,否则出错返回。
第22-27行,处理HELO指令,期望响应码为250。
第29-34行,处理MAIL FROM指令,期望响应码为250。
第36-41行,处理RCPT TO指令,期望响应码为250。
第44-49行,处理DATA指令,期望响应码为354。
第51-76行,生成邮件体,并发送。
第52-56行,如果$subject不为空,则查找邮件体中是否有主题部分,如果没有,则加上主题部分。
第59-63行,如果$from不为空,则查找邮件体中是否有发信人部分,如果没有,则加上发信人部分。
第66-70行,如果$to不为空,则查找邮件体中是否有收信人部分,如果没有,则加上收信人部分。
第73-74行,查找邮件体是否有了结束行,如果没有则加上邮件体的结束行(以"."作为单独的一行的特殊行)。
第76行,发送邮件体。
第78-83行,执行QUIT结否与服务器的连接,期望响应码为250。
第85行,返回处理成功标志(true)。
第81-91行,与服务器连接失败的处理。
 以上为整个send_mail类的实现,应该不是很难的。

以下に例を示します。

電子メール送信例

まず最も単純な例を示します:
1 include "sendmail.class.php3";
2 $email="Hello, this is a test Letter!";
3 $sendmail=new send_mail("smtp.263.net", "limodou", true); //調整情報を表示
4 if($sendmail->send("chatme@263.net", ") chatme@263.net", "test", $email))
5 {
6 echo "送信に成功しました!
";
7 }
8 else
9 {
10 echo "送信に失敗しました! ";
11 }
?>

1行目、send_mailクラスを読み込みます。
3行目:クラスのインスタンスを作成し、表示したくない場合は
$sendmail=new send_mail("smtp.263.net"); と設定します。
4 行目、メールを送信します。


シンプルですね。次に、前の MIME 電子メールの送信例に基づいて、HTML 添付ファイルを送信する例を示します。


include "MIME.class.php3";
//MIME メールの送信に関する記事では、このクラス ファイルの名前は MIME.class ですが、ここでは次のように変更しました

$ to = 'chatme@263.net'; //受信者のメールアドレスに変更されました
$str = "ニュースレター for ".date('MY', time());

//情報が変更されました私
$html_data = ''. $str. '

こんにちは!はテストです!

';

//MIME クラス インスタンスを生成します
$mime = new MIME_mail("chatme@263.net", $to, $str);

//HTML 添付ファイルを追加します
$mime->attach($html_data, "", HTML, BASE64);

//コメントアウトしてメール送信プロセスを使用します
//$mime->send_mail() ;

//メールを生成
$mime->gen_email(); "sendmail.class.php3"

//インスタンスを作成する
$sendmail=new send_mail("smtp.263.net", "limodou) 」 , true)

//メールを送信
$sendmail->send ( "
chatme@263.net
", "
chatme@263.net
", $str, $mime->email);
?>
コメントは非常に明確なので、これ以上の説明はしません。実際のアプリケーションで使用する場合は、send_mail コンストラクタの debug を false に設定するか、記述しないでください。



このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

解決策: 組織では PIN を変更する必要があります。 解決策: 組織では PIN を変更する必要があります。 Oct 04, 2023 pm 05:45 PM

ログイン画面に「組織から PIN の変更を求められています」というメッセージが表示されます。これは、個人のデバイスを制御できる組織ベースのアカウント設定を使用しているコンピューターで PIN の有効期限の制限に達した場合に発生します。ただし、個人アカウントを使用して Windows をセットアップした場合、エラー メッセージは表示されないのが理想的です。常にそうとは限りませんが。エラーが発生したほとんどのユーザーは、個人アカウントを使用して報告します。私の組織が Windows 11 で PIN を変更するように要求するのはなぜですか?アカウントが組織に関連付けられている可能性があるため、主なアプローチはこれを確認することです。ドメイン管理者に問い合わせると解決できます。さらに、ローカル ポリシー設定が間違っていたり、レジストリ キーが間違っていたりすると、エラーが発生する可能性があります。今すぐ

Windows 11 でウィンドウの境界線の設定を調整する方法: 色とサイズを変更する Windows 11 でウィンドウの境界線の設定を調整する方法: 色とサイズを変更する Sep 22, 2023 am 11:37 AM

Windows 11 では、新鮮でエレガントなデザインが前面に押し出されており、最新のインターフェイスにより、ウィンドウの境界線などの細部をカスタマイズして変更することができます。このガイドでは、Windows オペレーティング システムで自分のスタイルを反映した環境を作成するのに役立つ手順について説明します。ウィンドウの境界線の設定を変更するにはどうすればよいですか? + を押して設定アプリを開きます。 Windows [個人用設定] に移動し、[色の設定] をクリックします。ウィンドウの境界線の色の変更設定ウィンドウ 11" width="643" height="500" > [タイトル バーとウィンドウの境界線にアクセント カラーを表示する] オプションを見つけて、その横にあるスイッチを切り替えます。 [スタート] メニューとタスク バーにアクセント カラーを表示するにはスタート メニューとタスク バーにテーマの色を表示するには、[スタート メニューとタスク バーにテーマを表示] をオンにします。

Windows 11でタイトルバーの色を変更するにはどうすればよいですか? Windows 11でタイトルバーの色を変更するにはどうすればよいですか? Sep 14, 2023 pm 03:33 PM

デフォルトでは、Windows 11 のタイトル バーの色は、選択したダーク/ライト テーマによって異なります。ただし、任意の色に変更できます。このガイドでは、デスクトップ エクスペリエンスを変更し、視覚的に魅力的なものにするためにカスタマイズする 3 つの方法について、段階的な手順を説明します。アクティブなウィンドウと非アクティブなウィンドウのタイトル バーの色を変更することはできますか?はい、設定アプリを使用してアクティブなウィンドウのタイトル バーの色を変更したり、レジストリ エディターを使用して非アクティブなウィンドウのタイトル バーの色を変更したりできます。これらの手順を学習するには、次のセクションに進んでください。 Windows 11でタイトルバーの色を変更するにはどうすればよいですか? 1. 設定アプリを使用して + を押して設定ウィンドウを開きます。 Windows「個人用設定」に進み、

Windows 11/10修復におけるOOBELANGUAGEエラーの問題 Windows 11/10修復におけるOOBELANGUAGEエラーの問題 Jul 16, 2023 pm 03:29 PM

Windows インストーラー ページに「問題が発生しました」というメッセージとともに「OOBELANGUAGE」というメッセージが表示されますか?このようなエラーが原因で Windows のインストールが停止することがあります。 OOBE とは、すぐに使えるエクスペリエンスを意味します。エラー メッセージが示すように、これは OOBE 言語の選択に関連する問題です。心配する必要はありません。OOBE 画面自体から気の利いたレジストリ編集を行うことで、この問題を解決できます。クイックフィックス – 1. OOBE アプリの下部にある [再試行] ボタンをクリックします。これにより、問題が発生することなくプロセスが続行されます。 2. 電源ボタンを使用してシステムを強制的にシャットダウンします。システムの再起動後、OOBE が続行されます。 3. システムをインターネットから切断します。 OOBE のすべての側面をオフライン モードで完了する

Windows 11 でタスクバーのサムネイル プレビューを有効または無効にする方法 Windows 11 でタスクバーのサムネイル プレビューを有効または無効にする方法 Sep 15, 2023 pm 03:57 PM

タスクバーのサムネイルは楽しい場合もありますが、気が散ったり煩わしい場合もあります。この領域にマウスを移動する頻度を考えると、重要なウィンドウを誤って閉じてしまったことが何度かある可能性があります。もう 1 つの欠点は、より多くのシステム リソースを使用することです。そのため、リソース効率を高める方法を探している場合は、それを無効にする方法を説明します。ただし、ハードウェアの仕様が対応可能で、プレビューが気に入った場合は、有効にすることができます。 Windows 11でタスクバーのサムネイルプレビューを有効にする方法は? 1. 設定アプリを使用してキーをタップし、[設定] をクリックします。 Windows では、「システム」をクリックし、「バージョン情報」を選択します。 「システムの詳細設定」をクリックします。 [詳細設定] タブに移動し、[パフォーマンス] の下の [設定] を選択します。 「視覚効果」を選択します

Huawei GT3 ProとGT4の違いは何ですか? Huawei GT3 ProとGT4の違いは何ですか? Dec 29, 2023 pm 02:27 PM

多くのユーザーはスマートウォッチを選ぶときにファーウェイブランドを選択しますが、その中でもファーウェイ GT3pro と GT4 は非常に人気のある選択肢であり、多くのユーザーはファーウェイ GT3pro と GT4 の違いに興味を持っています。 Huawei GT3pro と GT4 の違いは何ですか? 1. 外観 GT4: 46mm と 41mm、材質はガラスミラー + ステンレススチールボディ + 高解像度ファイバーバックシェルです。 GT3pro: 46.6mm および 42.9mm、材質はサファイアガラス + チタンボディ/セラミックボディ + セラミックバックシェルです。 2. 健全な GT4: 最新の Huawei Truseen5.5+ アルゴリズムを使用すると、結果はより正確になります。 GT3pro: ECG 心電図と血管と安全性を追加

Windows 11 でのディスプレイ スケーリング ガイド Windows 11 でのディスプレイ スケーリング ガイド Sep 19, 2023 pm 06:45 PM

Windows 11 のディスプレイ スケーリングに関しては、好みが人それぞれ異なります。大きなアイコンを好む人もいれば、小さなアイコンを好む人もいます。ただし、適切なスケーリングが重要であることには誰もが同意します。フォントのスケーリングが不十分であったり、画像が過度にスケーリングされたりすると、作業中の生産性が大幅に低下する可能性があるため、システムの機能を最大限に活用するためにカスタマイズする方法を知る必要があります。カスタム ズームの利点: これは、画面上のテキストを読むのが難しい人にとって便利な機能です。一度に画面上でより多くの情報を確認できるようになります。特定のモニターおよびアプリケーションにのみ適用するカスタム拡張プロファイルを作成できます。ローエンド ハードウェアのパフォーマンスの向上に役立ちます。画面上の内容をより詳細に制御できるようになります。 Windows 11の使用方法

Windows 11で明るさを調整する10の方法 Windows 11で明るさを調整する10の方法 Dec 18, 2023 pm 02:21 PM

画面の明るさは、最新のコンピューティング デバイスを使用する上で不可欠な部分であり、特に長時間画面を見る場合には重要です。目の疲れを軽減し、可読性を向上させ、コンテンツを簡単かつ効率的に表示するのに役立ちます。ただし、設定によっては、特に新しい UI が変更された Windows 11 では、明るさの管理が難しい場合があります。明るさの調整に問題がある場合は、Windows 11 で明るさを管理するすべての方法を次に示します。 Windows 11で明るさを変更する方法【10の方法を解説】 シングルモニターユーザーは、次の方法でWindows 11の明るさを調整できます。これには、ラップトップだけでなく、単一のモニターを使用するデスクトップ システムも含まれます。はじめましょう。方法 1: アクション センターを使用する アクション センターにアクセスできる

See all articles