Maison  >  Article  >  cadre php  >  Explication détaillée de la façon d'introduire ThinkWechat.php dans TP et d'imprimer les journaux

Explication détaillée de la façon d'introduire ThinkWechat.php dans TP et d'imprimer les journaux

藏色散人
藏色散人avant
2021-08-09 09:47:072131parcourir

La colonne tutorielle suivante du thinkphp framework vous présentera comment introduire ThinkWechat.php dans TP et comment imprimer des journaux dans des fichiers journaux. J'espère que cela sera utile aux amis dans le besoin !

Développement de messages interactifs pour les comptes publics WeChat basés sur Thinkphp6

Après avoir regardé la pratique de thinkPHP, j'ai téléchargé le code du livre depuis github et je me suis préparé à exécuter le programme développé pour les comptes publics WeChat.
Cependant, comme le livre utilise ThinkPHP3.2.3 et que la dernière version est déjà la 6.0.X, je ne connais pas ThinkPHP de toute façon, j'ai donc téléchargé la dernière version à utiliser. Je m'attendais à ce qu'il y ait des problèmes pour exécuter le programme en raison des différentes versions. Ce que je pense, c'est que nous devrions résoudre chaque problème un par un. De manière inattendue, j’ai rencontré beaucoup de difficultés et il m’a fallu deux jours pour lancer le programme. Enfin, j'ai modifié un peu de code dans le framework.

Sans plus attendre, permettez-moi de lister par ordre les difficultés que j'ai rencontrées.

Comment introduire ThinkWechat.php dans TP

Dans le livre, ThinkWechat.php est placé sous /Application/Home/Library. Mais TP6 n'a plus d'application, j'ai donc créé un nouveau répertoire de bibliothèque sous /app et y ai placé les fichiers.

Vous devez introduire ce fichier dans Index.php

utiliser applibraryThinkWechat ;use applibraryThinkWechat;

在ThinkWechat.php文件中添加namespace

namespace applibrary;

Class 'applibrarySimpleXMLElement' not found

一开始,百度说是要在环境上安装php7-xml. 我的macmini需要用brew来安装,很久没用brew,brew update慢死了,按照百度的帖子,替换了阿里云的链接。
结果还是不行。弄brew弄了几个小时。后来不知道怎么发现,原来tp6里面用了namespace,所以在使用SimpleXMLElement的时候,要在文件开头写如下语句
use SimpleXMLElement;

TP6怎么打印日志到日志文件

因为是和微信公众号进行交互,我不知道有什么办法方便调试,试过了微信提供的接口调试工具,但是也仅仅能够检查参数设置是否正确。于是我用了最笨的打印日志的方法。
要打印日志需要在TP6中做以下设置:

在config/log.php 中

1.设置日志记录级别

'level'        => ['emergency'],

我调试时几乎把所有的level值都写到这里了。

1.设置日志保存目录

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

2.然后在程序中用下面的语句实时写入日志文件

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

关注测试公众号后,输入999,可以收到正常回复。输入1 程序则退出

这个问题卡了我大半天!!

一开始,我以为是返回给微信平台的response 有问题,因为我在ThinkWechat.php中打印了很多日志,发现只要我输入除999以外的信息,data2xml方法总是不能完全执行,日志在
$node = dom_import_simplexml($child);之后就无法打印。

我一直以为是$node->appendChild($node->ownerDocument->createCDATASection($value));
这句代码执行有问题。
因此还从《微信公众平台开发》一书中找到通过设置xml模板中,用sprintf方法替换模板中的变量来生成response的xml。

这样做的结果是,我能在日志中看到response xml 成功生成,但是输入1仍然没有得到我期望的回复,应该是没有任何回复,显示“该公众号暂时无法提供服务,请稍后再试”,并且才程序也是立即退出了。

后来我发现,自己随便写的程序,比如公众号每次都回复用户输入的信息,像应声桶那样,就没有问题,程序也不退出。我突然想着会不会是和session有关?因为源代码中用到了session来实现用户的注册和登录。
我看了下TP6的开发文档,果然,里面写到session默认是没初始化的。这里我有点欲哭无泪。

按照文档说明,我打开了session:

1.在app/middleware.php 中去掉thinkmiddlewareSessionInit::class

Ajouter un espace de noms dans le fichier ThinkWechat.php

applibrary d'espace de noms ;

Classe 'applibrarySimpleXMLElement' introuvable

Au début, Baidu a dit que php7-xml devrait être installé sur l'environnement. Mon Macmini doit être installé avec Brew. Je n'ai pas utilisé Brew depuis longtemps. extrêmement lent Selon le message de Baidu, remplacement du lien vers Alibaba Cloud. 🎜Le résultat ne fonctionne toujours pas. Je l'ai brassé pendant plusieurs heures. Je ne sais pas comment j'ai découvert plus tard que l'espace de noms est utilisé dans TP6, donc lorsque vous utilisez SimpleXMLElement, vous devez écrire l'instruction suivante au début du fichier🎜use SimpleXMLElement;🎜🎜🎜Comment pour imprimer les journaux dans un fichier journal dans TP6🎜🎜 🎜Parce que j'interagis avec le compte officiel WeChat, je ne sais pas comment faciliter le débogage. J'ai essayé l'outil de débogage d'interface fourni par WeChat, mais il n'a pu vérifier que si le fichier était utilisé. les réglages des paramètres étaient corrects. J'ai donc utilisé la méthode la plus stupide pour imprimer les journaux. 🎜Pour imprimer les journaux, vous devez effectuer les réglages suivants dans TP6 : 🎜🎜Dans config/log.php 🎜1 Définir le niveau de journalisation 🎜'level' => ['emergency'],🎜. 🎜 Lors du débogage, j'ai écrit ici presque toutes les valeurs de niveau. 🎜1. Définissez le répertoire de sauvegarde des journaux 🎜'path' => App()->getRuntimePath() .'/log',🎜2. Utilisez ensuite l'instruction suivante pour écrire en temps réel dans. le programme Log file🎜Log::write('index _get session id before set ID '. Session::getId(), 'notice');🎜🎜🎜Après avoir suivi le test du compte officiel, entrez 999, vous pouvez recevoir une réponse normale. Entrez 1 et le programme se terminera🎜🎜🎜Ce problème m'est resté pendant la majeure partie de la journée ! ! 🎜🎜Au début, je pensais qu'il y avait un problème avec la réponse renvoyée à la plateforme WeChat, car j'imprimais beaucoup de journaux dans ThinkWechat.php, et j'ai découvert que tant que je saisissais des informations autres que 999, la méthode data2xml ne pouvait pas être entièrement exécuté et les journaux étaient dans 🎜 $node = dom_import_simplexml($child); ne peut pas être imprimé après cela. 🎜🎜J'ai toujours pensé que c'était $node->appendChild($node->ownerDocument->createCDATASection($value));🎜Il y a un problème avec l'exécution de ce code. 🎜J'ai donc également découvert dans le livre "WeChat Public Platform Development" qu'en définissant le modèle XML, en utilisant la méthode sprintf pour remplacer les variables dans le modèle afin de générer la réponse XML. 🎜🎜Le résultat est que je peux voir dans le journal que la réponse XML a été générée avec succès, mais la saisie de 1 n'a toujours pas obtenu la réponse que j'attendais. Il ne devrait y avoir aucune réponse, et cela a montré "Ce compte officiel est temporairement incapable". pour fournir des services, veuillez patienter. "Réessayez", et le programme s'est arrêté immédiatement. 🎜🎜Plus tard, j'ai découvert que si j'écrivais un programme avec désinvolture, comme un compte public qui répondait à chaque fois aux informations saisies par l'utilisateur, comme un seau de réponses, il n'y aurait aucun problème et le programme ne se terminerait pas. Je me suis soudain demandé si cela pouvait être lié à la séance ? Parce que la session est utilisée dans le code source pour implémenter l'enregistrement et la connexion des utilisateurs. 🎜J'ai regardé la documentation de développement de TP6, et bien sûr, elle dit que la session n'est pas initialisée par défaut. J'ai envie de pleurer ici. 🎜🎜En suivant les instructions de la documentation, j'ai ouvert la session : 🎜🎜1. Supprimez le commentaire de thinkmiddlewareSessionInit::class dans app/middleware.php. 🎜🎜2. Et supprimez session_start() dans le code. Parce que TP6 ne prend en charge que les sessions d'exploitation via les méthodes de classe Session et les fonctions d'assistance de session, il ne prend pas en charge toutes les fonctions session_xx. 🎜🎜Une fois la session ouverte, le programme ne se fermera plus. Mais un nouveau problème est survenu. Après avoir entré 999, entrez 1. Le compte officiel a répondu correctement. Veuillez entrer le nom d'utilisateur, mais la réponse après avoir entré le nom d'utilisateur était la même que celle de 999. Lorsque vous y êtes invité, entrez 1 pour vous inscrire et entrez 2 pour vous connecter. La bonne solution devrait être de demander un nom d'utilisateur. 🎜

À ce moment-là, j'ai découvert que plusieurs fichiers de session étaient générés dans le répertoire runtime/session. Pour le même utilisateur, il ne doit y avoir qu’un seul fichier de session correct. Cela équivaut à la génération d'un nouveau fichier de session à chaque fois que l'utilisateur interagit avec le compte officiel, de sorte que les informations précédemment saisies par l'utilisateur ne peuvent pas être obtenues.

Baidu a découvert plus tard que la raison en est que la

session est stockée côté serveur, il est donc nécessaire d'utiliser des cookies client pour distinguer la session de chaque utilisateur. Le serveur WeChat n'envoie pas de cookies au serveur du développeur, donc les sessions. basés sur des cookies ne peuvent pas être utilisés.
Mais tant qu'un session_id unique est défini pour chaque utilisateur, le même effet peut être obtenu.
L'identifiant WeChat de chacun est unique, nous pouvons donc utiliser l'identifiant WeChat comme identifiant de session de l'utilisateur, ou nous pouvons l'utiliser après le cryptage md5.

Je prévois d'utiliser la valeur de FromUserName comme identifiant de session. C'est-à-dire le propre openid de chaque utilisateur. Cependant, TP6 ne prend pas en charge la méthode session_id() pour définir l'ID de session. J'ai lu plus tard la documentation et découvert que Session::setId peut être utilisé pour définir le SessionID, mais je ne sais pas pourquoi un sessionID différent est toujours généré à chaque fois.

Il est écrit sur Internet que vous pouvez utiliser openid. J'ai découvert que chaque fois que l'URL envoyée par le compte public WeChat au serveur est accompagnée d'openid, j'ai configuré openid dans session.php, en espérant que TP6 utilisera openid dans la demande comme identifiant de session à chaque fois. Mais cela n’a toujours pas eu d’effet.

Le fichier session.php de TP6 a la configuration suivante :

La variable de soumission de SESSION_ID résout le problème du téléchargement flash inter-domaines
'var_session_id' => 'openid','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 response没有关系。于是我又用回以前的ThinkWechat.php,却发现runtime/session目录中没有生成session文件。

检查后才发现,原始的ThinkWechat.php的response方法最后是

exit($xml->asXML());

而TP6官方文档有以下提醒:

注意,Session写入数据的操作会在请求结束的时候统一进行本地化存储,所以不要在写入Session数据之后使用exit等中断操作,可能会导致Session没有正常写入。

因此我把exit语句改为return $xml->asXML();

Vérifié le setId du inférieur frame, Le code original est le suivant

rrreee

Il s'avère que l'identifiant de session doit être une chaîne de 32 bits contenant des caractères alphanumériques. S'il ne répond pas aux exigences (la longueur de l'openid est de 28 bits), l'heure actuelle sera utilisée comme. l'identifiant de session, j'ai donc changé le setId comme suit, puis l'identifiant de session est imprimé dans la méthode d'index et s'avère être le même à chaque fois.
rrreee
Exécutez le programme et tout fonctionne bien.

En ce moment, je pense que tous les problèmes que j'ai rencontrés auparavant ne devraient rien avoir à voir avec la réponse XML. J'ai donc utilisé le précédent ThinkWechat.php, mais j'ai constaté que le fichier de session n'était pas généré dans le répertoire runtime/session.

Après vérification, j'ai découvert que la méthode de réponse du ThinkWechat.php original finissait par être
🎜exit($xml->asXML());🎜🎜Et le document officiel TP6 a le rappel suivant : 🎜🎜 Notez que l'opération d'écriture des données dans la session sera uniformément stockée localement à la fin de la requête, n'utilisez donc pas d'opérations d'interruption telles que la sortie après l'écriture des données de la session, ce qui pourrait empêcher l'écriture de la session normalement . 🎜🎜J'ai donc modifié l'instruction de sortie en return $xml->asXML(); À ce moment-là, le fichier de session était généré normalement et les informations répondues par le compte officiel étaient également correctes. 🎜🎜Le code PS a été hébergé sur github🎜https://github.com/sarawang9012/thinkwechat🎜🎜🎜Recommandations associées : 🎜Les 10 derniers didacticiels vidéo thinkphp🎜🎜🎜

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer