ホームページ  >  記事  >  PHPフレームワーク  >  TPにThinkWechat.phpを導入してログを印刷する方法を詳しく解説

TPにThinkWechat.phpを導入してログを印刷する方法を詳しく解説

藏色散人
藏色散人転載
2021-08-09 09:47:072143ブラウズ

thinkphp フレームワーク の次のチュートリアル コラムでは、TP に ThinkWechat.php を導入する方法と、ログをログ ファイルに出力する方法を紹介します。困っている友達!

Thinkphp6 に基づく WeChat 公開アカウント向けのインタラクティブ メッセージ開発

thinkPHP の実践を見た後、本のコードを github からダウンロードし、実行する準備をしました。 WeChat 公開アカウント用に開発されたプログラム。

ただし、本書では ThinkPHP3.2.3 を使用しており、最新バージョンは既に 6.0.X なので、そもそも ThinkPHP に詳しくないので、最新バージョンをダウンロードして使用しました。バージョンが異なるため、プログラムの実行に問題が発生するだろうと予想していました。私が思うのは、問題を一つずつ解決していくべきだということです。思いがけず、多くの困難に遭遇し、プログラムを実行するまでに 2 日かかりました。最後に、フレームワーク内のコードを少し変更しました。

さっそく、私が遭遇した困難を順番に挙げてみましょう。

TP に ThinkWechat.php を導入する方法

本書では、ThinkWechat.php は /Application/Home/Library に配置されています。ただし、TP6 には Application がなくなったので、/app の下に新しいライブラリ ディレクトリを作成し、そこにファイルを置きました。

このファイルを Index.php に導入する必要があります。

app\library\ThinkWechat を使用します;

ThinkWechat.php に名前空間を追加します##ファイル

#namespace app\library;

Class 'app\library\SimpleXMLElement' not found

冒頭で、Baidu は php7 をインストールする必要があると述べました。環境 - xml. 私の macmini は brew でインストールする必要があります. 長い間 brew を使用していません. Brew の更新が非常に遅いです. Baidu の投稿によると、Alibaba Cloud へのリンクを置き換えました。

結果はまだ機能しません。数時間かけて煮込みました。名前空間が tp6 で使用されていたことを後からどうやって知ったのかはわかりません。そのため、SimpleXMLElement を使用する場合は、ファイルの先頭に次のステートメントを記述する必要があります。


use SimpleXMLElement;

TP6 はどうですか ログ ファイルにログを出力します

WeChat 公式アカウントを使用しているため、デバッグを容易にする方法がわかりません。インターフェース デバッグ ツールを試してみました。 WeChat が提供していますが、パラメーターの設定が正しいかどうかを確認することしかできません。そこで私はログを出力するという最も愚かな方法を使用しました。

ログを出力するには、TP6 で次の設定を行う必要があります:


config/log.php

1. ログ レベルを設定します

'level' => ['緊急'],

デバッグ時にほぼすべてのレベル値をここに書きました。

1. ログ保存ディレクトリを設定します

'path' => App()->getRuntimePath() .'/log',

2. 次に、以下を使用します。プログラム ステートメントはリアルタイムでログ ファイルに書き込まれます。

Log::write('index _get session id before set ID '.Session::getId(), 'notice');

テスト公開アカウントをフォローした後、「999」と入力すると通常の返信が届きます。 1 を入力すると、プログラムが終了します。

この問題は、一日のほとんどの間私を悩ませました。 !

最初は、WeChat プラットフォームに返される応答に問題があるのではないかと思いました。ThinkWechat.php に大量のログを出力したところ、999 以外の情報を入力すると data2xml がメソッドを完全に実行できませんでした。

$node = dom_import_simplexml($child);
の後にログを出力できません。 ずっと

$node->appendChild($node->ownerDocument->createCDATASection($value));

実行に問題があったと思っていましたこのコードの。 そこで、xmlテンプレートを設定し、テンプレート内の変数をsprintfメソッドで置き換えることでレスポンスxmlが生成されることも「WeChatパブリックプラットフォーム開発」という書籍で知りました。

この結果、応答 xml が正常に生成されたことがログで確認できますが、「1」を入力しても期待した応答が得られませんでした。応答がないはずで、次のように表示されます。 「この公式アカウントは一時的にサービスを提供できません。後ほどもう一度お試しください」と表示され、プログラムもすぐに終了してしまいました。

後で、ユーザーが入力した情報に毎回応答する公開アカウントなど、応答バケットのようなプログラムをランダムに書いた場合、問題は発生せず、プログラムは終了しないことがわかりました。 。ふと思ったのですが、セッションに関係があるのでは?ユーザー登録とログインを実装するためにソースコードでセッションが使用されるためです。

TP6 の開発ドキュメントを見てみると、案の定、セッションはデフォルトでは初期化されないと記載されています。ここで泣きそうになります。


ドキュメントに従って、セッションを開きました:

1. app/middleware.php のコメント

\think\middleware\SessionInit::class

を削除します。 2. コード内の session_start() を削除します。 TP6 は、Session クラスのメソッドとセッション ヘルパー関数を介したセッションの操作のみをサポートしており、すべての session_xx 関数をサポートしているわけではないためです。

セッションが開かれると、プログラムは終了しなくなります。しかし、新たな問題が発生しました。999を入力した後、1を入力してください。公式アカウントは正しく応答しました。ユーザー名を入力してください。しかし、ユーザー名を入力した後の応答は999を入力した場合と同じでした。」プロンプトが表示されたら、1 を入力して登録し、2 を入力してログインします。正しいのは、ユーザー名の入力を求めるプロンプトです。

この時、runtime/sessionディレクトリに複数のセッションファイルが生成されていることが分かりました。同じユーザーの場合、正しいセッション ファイルは 1 つだけ存在する必要があります。これは、ユーザーが公式アカウントと対話するたびに新しいセッション ファイルが生成されることに相当し、ユーザーが以前に入力した情報を取得することはできません。

Baidu は後に、この理由が

セッションがサーバー側に保存されているためであることを発見しました。そのため、各ユーザーのセッションを区別するには、クライアントの Cookie を使用する必要があります。WeChat サーバーは、 Cookie を開発者サーバーに送信するため、Cookie ベースのセッションは使用できません。
ただし、ユーザーごとに一意の session_id が設定されている限り、同じ効果が得られます。
全員の WeChat ID は一意であるため、WeChat ID をユーザーの session_id として使用することも、MD5 暗号化後に使用することもできます。

FromUserName の値をセッション ID として使用する予定です。つまり、各ユーザー独自の openid です。ただし、TP6 は、sessionid を設定する session_id() メソッドをサポートしていません。後でドキュメントを読んだところ、Session::setId を使用して SessionID を設定できることがわかりましたが、なぜ毎回異なる sessionID が生成されるのかわかりません。

インターネットでは、openid を使用できると書かれていますが、WeChat の公開アカウントからサーバーに送信される URL には必ず openid が含まれていることがわかり、TP6 がそうなることを期待して、session.php で openid を設定しました。リクエストでは毎回 openid をセッション ID として使用します。しかし、それでも効果はありませんでした。

TP6 の session.php の構成は次のとおりです:

フラッシュ アップロードのクロスドメインを解決するための SESSION_ID 送信変数
'var_session_id' => 'openid',

フレームワークの setId を確認したところ、元のコードは次のとおりです

public function setId($id = null): void
    {
        $this->id = is_string($id) && strlen($id) === 32 && ctype_alnum($id) ? $id : md5(microtime
        (true).session_create_id());
    }

sessionid は英数字を含む 32 ビット文字列である必要があることがわかりました。要件を満たしていない場合は ( openid の長さは 28 ビットです)、現在の時刻が sessionid として使用されるため、setId を次のように変更し、index メソッドで sessionid を出力したところ、毎回同じであることがわかりました。

public function setId($id = null): void
    {
        $this->id = is_string($id) && strlen(md5($id)) === 32 && ctype_alnum(md5($id)) ? md5($id) : md5(microtime
        (true).session_create_id());
    }

プログラムを実行すると、すべてが正常に動作します。素晴らしい気分です。

現時点では、以前に遭遇したすべての問題は XML 応答とは関係がないはずだと思います。そこで、以前の ThinkWechat.php を使用しましたが、セッション ファイルが runtime/session ディレクトリに生成されていないことがわかりました。

確認したところ、元の ThinkWechat.php の応答メソッドは

exit($xml->asXML());

で終わっていることがわかりました。

TP6 公式ドキュメントには次の注意事項があります:

セッションにデータを書き込む操作はローカライズされ、リクエストの最後に均一に保存されるため、終了やその他の割り込み操作を使用しないでください。セッション データの書き込み後、セッションが正常に書き込まれなくなる可能性があります。

そこで、exit ステートメントを return $xml->asXML(); に変更しました。このとき、セッションファイルは正常に生成され、公式アカウントから返信された情報も正しい。

PS コードは github でホストされています

https://github.com/sarawang9012/thinkwechat

関連する推奨事項: 最新の 10 件の thinkphp ビデオ チュートリアル

以上がTPにThinkWechat.phpを導入してログを印刷する方法を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。