ただし、本書では ThinkPHP3.2.3 を使用しており、最新バージョンは既に 6.0.X なので、そもそも ThinkPHP に詳しくないので、最新バージョンをダウンロードして使用しました。バージョンが異なるため、プログラムの実行に問題が発生するだろうと予想していました。私が思うのは、問題を一つずつ解決していくべきだということです。思いがけず、多くの困難に遭遇し、プログラムを実行するまでに 2 日かかりました。最後に、フレームワーク内のコードを少し変更しました。
TP に ThinkWechat.php を導入する方法
本書では、ThinkWechat.php は /Application/Home/Library に配置されています。ただし、TP6 には Application がなくなったので、/app の下に新しいライブラリ ディレクトリを作成し、そこにファイルを置きました。 このファイルを Index.php に導入する必要があります。app\library\ThinkWechat を使用します;
Class 'app\library\SimpleXMLElement' not found
冒頭で、Baidu は php7 をインストールする必要があると述べました。環境 - xml. 私の macmini は brew でインストールする必要があります. 長い間 brew を使用していません. Brew の更新が非常に遅いです. Baidu の投稿によると、Alibaba Cloud へのリンクを置き換えました。
結果はまだ機能しません。数時間かけて煮込みました。名前空間が tp6 で使用されていたことを後からどうやって知ったのかはわかりません。そのため、SimpleXMLElement を使用する場合は、ファイルの先頭に次のステートメントを記述する必要があります。
use SimpleXMLElement;
WeChat 公式アカウントを使用しているため、デバッグを容易にする方法がわかりません。インターフェース デバッグ ツールを試してみました。 WeChat が提供していますが、パラメーターの設定が正しいかどうかを確認することしかできません。そこで私はログを出力するという最も愚かな方法を使用しました。
ログを出力するには、TP6 で次の設定を行う必要があります:
config/log.php
デバッグ時にほぼすべてのレベル値をここに書きました。
2. 次に、以下を使用します。プログラム ステートメントはリアルタイムでログ ファイルに書き込まれます。
この問題は、一日のほとんどの間私を悩ませました。 !
最初は、WeChat プラットフォームに返される応答に問題があるのではないかと思いました。ThinkWechat.php に大量のログを出力したところ、999 以外の情報を入力すると data2xml がメソッドを完全に実行できませんでした。
$node = dom_import_simplexml($child);
の後にログを出力できません。 ずっと
実行に問題があったと思っていましたこのコードの。
そこで、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