モニター教師 Ruan Yifeng のブログ
Ruan Yifeng は非常に強力な人物であり、経済学の博士号を持ち、以下のような幅広い知識を持っています。コンピューターやアルゴリズム、英語、文学的才能など、彼のブログは最も人気のあるブログの 1 つとして考えられます。
私はよく彼のブログを読みに行きますが、時々、久しぶりにもう一度チェックすると、新しい記事がいくつかあることに気づき、彼のブログに新しい記事があるときにそれを監視するプログラムを自分で作成できないかと考えていました。記事があれば、彼はできるだけ早く私にプッシュしてくれるでしょう。
彼のブログにはフィードがあり、XML 形式のドキュメントを返すインターフェースです。このインターフェースは最新の記事リスト、合計 15 件の記事を監視できます。このインターフェイスにはいくつかの記事が含まれています。記事リストの変更は、彼の記事の更新を間接的に検出するために使用されます。新しい記事がある場合、電子メールがすぐに私のメールボックスに送信され、ルアン先生の最新の記事をできるだけ早く入手できます。
これは設計アイデアの図です:
最初は、PHP のネイティブ関数 simplexml_load_string を使用して、解析された SimpleXMLElement オブジェクトを取得します。最初のいくつかの記事はルアン先生によって更新されました。そして、redisに設定されている送信済み記事リストと比較し、新たな更新があればUDPserverに更新情報を送信し、UDPserverからユーザーリストにメールを送信させます。検出プログラムは周期的に実行され、10 分ごとに実行されます。
一度アイデアがわかれば、コーディングは非常に速くなります(ここで何度か最適化されており、最初はアイデアがあまり明確ではありませんでした。途中で変更しました)もちろん、始める前にできるだけ多くのアイデアを完成させながら、ゆっくりと検討する必要があります)。
強力な PHP 依存関係管理ツールである Composer を使用します。PHP をよく使用する開発者は、このツールに精通しているはずです。ドキュメントは中国語で書かれているため、簡単にブレインストーミングを行うことができます。理解すること。この小さなシステムは、phpmailer
、predis
、workerman
の 3 つのクラス ライブラリを使用します。 1 つ目は、電子メールを送信するためのクラス ライブラリです。ここをクリックすると、関連情報が表示されます。2 つ目は、PHP の redis インターフェイスのカプセル化です。3 つ目は、UDPserver を作成するためのクラス ライブラリです。 . 彼の公式ウェブサイトはこちらです。
最初に新しいプロジェクト ディレクトリを作成し、次にプロジェクト ディレクトリに入って依存関係をインストールします
<code>mkdir blog-observercd blog-observercomposer require phpmailer/phpmailercomposer require predis/prediscomposer require workerman/workerman</code>
上記のコマンドを実行すると、プロジェクトディレクトリ blog -observer ディレクトリの下に、次のファイル composer.json
、composer.lock
およびフォルダー vender
が表示されます。 これで、composer.json の内容は次のようになります。
<code class="sourceCode json"><span class="fu">{</span> <span class="dt">"require"</span><span class="fu">:</span> <span class="fu">{</span> <span class="dt">"phpmailer/phpmailer"</span><span class="fu">:</span> <span class="st">"^5.2"</span><span class="fu">,</span> <span class="dt">"predis/predis"</span><span class="fu">:</span> <span class="st">"^1.0"</span><span class="fu">,</span> <span class="dt">"workerman/workerman"</span><span class="fu">:</span> <span class="st">"^3.3"</span> <span class="fu">}</span><span class="fu">}</span></code>
以下はサーバープログラムなのでデーモンとして設定されています。 UDPserver は udp://127.0.0.1:1234
<code class="sourceCode php">daemonize<span class="ot">();</span><span class="kw">while</span><span class="ot">(</span><span class="dv">1</span><span class="ot">)</span>{ <span class="co">//获取最新的几篇文章,看看是否需要推送</span> <span class="kw">$c</span> = <span class="fu">file_get_contents</span><span class="ot">(</span><span class="kw">XML_URL</span><span class="ot">);</span> <span class="kw">$parse</span> = <span class="er">@</span><span class="fu">simplexml_load_string</span><span class="ot">(</span><span class="kw">$c</span><span class="ot">);</span> <span class="kw">if</span><span class="ot">(</span><span class="kw">$parse</span><span class="ot">)</span> { <span class="kw">$count</span> = <span class="fu">count</span><span class="ot">(</span><span class="kw">$parse</span>->entry<span class="ot">);</span> <span class="kw">$count</span> = <span class="kw">$count</span> > <span class="kw">RECENT_NUM</span> <span class="ot">?</span> <span class="kw">RECENT_NUM</span> <span class="ot">:</span> <span class="kw">$count</span><span class="ot">;</span> <span class="kw">$maynew</span> = <span class="ot">[];</span> <span class="kw">for</span><span class="ot">(</span><span class="kw">$i</span> = <span class="dv">0</span><span class="ot">;</span> <span class="kw">$i</span> < <span class="kw">$count</span><span class="ot">;</span> <span class="kw">$i</span>++<span class="ot">)</span> { <span class="kw">$maynew</span><span class="ot">[</span><span class="kw">$parse</span>->entry<span class="ot">[</span><span class="kw">$i</span><span class="ot">]</span>-><span class="fu">link</span>->attributes<span class="ot">()</span>->href-><span class="fu">__toString</span><span class="ot">()]</span> = <span class="kw">$parse</span>->entry<span class="ot">[</span><span class="kw">$i</span><span class="ot">]</span>->title-><span class="fu">__toString</span><span class="ot">();</span> } <span class="kw">$body</span> = <span class="st">""</span><span class="ot">;</span> <span class="co">//是否推送</span> <span class="kw">foreach</span><span class="ot">(</span><span class="kw">$maynew</span> <span class="kw">as</span> <span class="kw">$url</span> => <span class="kw">$title</span><span class="ot">)</span> { <span class="kw">if</span><span class="ot">(</span><span class="kw">$client</span>->sadd<span class="ot">(</span><span class="kw">SENDED_SET_KEY</span><span class="ot">,</span> <span class="kw">$url</span><span class="ot">))</span> { <span class="co">//send EMAIL</span> <span class="kw">$body</span> .= <span class="st">"<a href='"</span>.<span class="kw">$url</span>.<span class="st">"'>"</span>.<span class="kw">$title</span>.<span class="st">"</a><br>"</span><span class="ot">;</span> } } <span class="kw">if</span><span class="ot">(</span><span class="kw">$body</span><span class="ot">)</span> { <span class="kw">$msg</span> = <span class="ot">[];</span> <span class="kw">$msg</span><span class="ot">[</span><span class="st">'type'</span><span class="ot">]</span> = <span class="dv">1</span><span class="ot">;</span> <span class="kw">$msg</span><span class="ot">[</span><span class="st">'mailbody'</span><span class="ot">]</span> = <span class="kw">$body</span><span class="ot">;</span> <span class="kw">$start</span> = <span class="dv">0</span><span class="ot">;</span> <span class="kw">while</span><span class="ot">(</span><span class="kw">$mailaddrs</span> = <span class="kw">$client</span>->lrange<span class="ot">(</span><span class="kw">EMAIL_LIST_KEY</span> <span class="ot">,</span><span class="kw">$start</span><span class="ot">,</span> <span class="ot">(</span><span class="kw">$start</span> + <span class="kw">EVERY_SEND_NUM</span> -<span class="dv">1</span> <span class="ot">)))</span> { <span class="kw">$msg</span><span class="ot">[</span><span class="st">'mailaddrs'</span><span class="ot">]</span> = <span class="kw">$mailaddrs</span><span class="ot">;</span> <span class="kw">$send_msg</span> = <span class="fu">json_encode</span><span class="ot">(</span><span class="kw">$msg</span><span class="ot">);</span> <span class="fu">socket_sendto</span><span class="ot">(</span><span class="kw">$sock</span><span class="ot">,</span> <span class="kw">$send_msg</span><span class="ot">,</span> <span class="fu">strlen</span><span class="ot">(</span><span class="kw">$send_msg</span><span class="ot">),</span> <span class="dv">0</span><span class="ot">,</span> <span class="st">'127.0.0.1'</span><span class="ot">,</span> <span class="dv">1234</span><span class="ot">);</span> <span class="kw">$start</span> += <span class="kw">EVERY_SEND_NUM</span><span class="ot">;</span> } } } <span class="fu">sleep</span><span class="ot">(</span><span class="kw">GAP_SECONDS</span><span class="ot">);</span>}</code>
workerman を使用すると、UDPserver を自分で作成するよりも簡単に実装できます。 。
<code class="sourceCode php"><span class="kw">$udp_worker</span> = <span class="kw">new</span> Workerman\Worker<span class="ot">(</span><span class="st">"udp://0.0.0.0:"</span>.<span class="kw">MAIL_UDP_PORT</span><span class="ot">);</span><span class="kw">$udp_worker</span>-><span class="fu">count</span> = <span class="dv">2</span><span class="ot">;</span><span class="kw">$udp_worker</span>->onMessage = <span class="kw">function</span><span class="ot">(</span><span class="kw">$connection</span><span class="ot">,</span> <span class="kw">$data</span><span class="ot">)</span> <span class="kw">use</span> <span class="ot">(</span><span class="kw">$mail</span><span class="ot">)</span>{ <span class="kw">$arr</span> = <span class="fu">json_decode</span><span class="ot">(</span><span class="kw">$data</span><span class="ot">,</span> <span class="kw">true</span><span class="ot">);</span> <span class="kw">switch</span><span class="ot">(</span><span class="kw">$arr</span><span class="ot">[</span><span class="st">'type'</span><span class="ot">])</span> { <span class="co">//发送邮件</span> <span class="kw">case </span><span class="st">'1'</span><span class="ot">:</span> { <span class="kw">$mailaddrs</span> = <span class="kw">$arr</span><span class="ot">[</span><span class="st">'mailaddrs'</span><span class="ot">];</span> <span class="kw">if</span><span class="ot">(</span>!<span class="fu">empty</span><span class="ot">(</span><span class="kw">$mailaddrs</span><span class="ot">)</span> && <span class="kw">$arr</span><span class="ot">[</span><span class="st">'mailbody'</span><span class="ot">])</span> { <span class="kw">foreach</span><span class="ot">(</span><span class="kw">$mailaddrs</span> <span class="kw">as</span> <span class="kw">$to</span><span class="ot">)</span> { <span class="kw">$mail</span>->clearAddresses<span class="ot">();</span> <span class="kw">$mail</span>->AddAddress<span class="ot">(</span><span class="kw">$to</span><span class="ot">);</span> <span class="kw">$mail</span>->Body = <span class="kw">$arr</span><span class="ot">[</span><span class="st">'mailbody'</span><span class="ot">];</span> <span class="kw">if</span><span class="ot">(</span>!<span class="kw">$mail</span>->Send<span class="ot">())</span> { <span class="fu">echo</span> <span class="st">"发送邮件失败:</span><span class="kw">\n</span><span class="st">"</span>.<span class="st">"address:"</span>.<span class="kw">$to</span>.<span class="st">"</span><span class="kw">\n</span><span class="st">"</span><span class="ot">;</span> } } } <span class="kw">break</span><span class="ot">;</span> } <span class="kw">default:</span> <span class="kw">break</span><span class="ot">;</span> }}<span class="ot">;</span>Workerman\Worker::runAll<span class="ot">();</span></code>
これで、すべての設計とコーディング作業が完了しました。プロセスが開始されたら、プログラムを開始します。デーモンとして実行されます。ターミナルが閉じられても停止しません。
<code>php xmldup.php startphp xmlmail.php</code>
もちろん、デーモンのプロセスは通常 d
の文字で終了し、起動が非常に遅いなど、多くの不規則性があります。便利です。スクリプトを 2 回開始する必要があります (笑)。もちろん、これは単なる遊びです。実際に完成したシステムを設計したい場合は、多くのことを検討することになるでしょう。
Github アドレスは次のとおりです: blog-observer を試してみるときは、メール名とパスワードを忘れずに変更してください。
ルアン先生の最新の記事をできるだけ早く入手したい人は、私にメールを送ってください。あなたのメールアドレスをメールリストに追加しますが、登録されるという保証はありません。コンピューターの電源を切るとプログラムが停止します~