Home  >  Article  >  PHP Framework  >  Detailed explanation of how to introduce ThinkWechat.php in TP and print logs

Detailed explanation of how to introduce ThinkWechat.php in TP and print logs

藏色散人
藏色散人forward
2021-08-09 09:47:072143browse

The following tutorial column of thinkphp framework will introduce to you how to introduce ThinkWechat.php in TP and how to print logs to log files. I hope it will be helpful to friends in need!

Interactive message development for WeChat public accounts based on Thinkphp6

After watching thinkPHP practice, I downloaded the code in the book from github and prepared to run it A program developed for WeChat public accounts.
However, because the book uses ThinkPHP3.2.3, and the latest version is already 6.0.X, I am not familiar with ThinkPHP anyway, so I downloaded the latest version to use. I expected that there would be problems running the program because of the different versions. What I think is that we should solve each problem one by one. Unexpectedly, I encountered a lot of difficulties and it took me two days to get the program running. Finally, I changed a little bit of code in the framework.

Without further ado, let me list the difficulties I encountered in turn.

How to introduce ThinkWechat.php in TP

In the book, ThinkWechat.php is placed under /Application/Home/Library. But TP6 no longer has Application, so I created a new library directory under /app and put the files in it.

You need to introduce this file in Index.php

use app\library\ThinkWechat;

Add namespace## in the ThinkWechat.php file

#namespace app\library;

Class 'app\library\SimpleXMLElement' not found

At the beginning, Baidu said that php7 should be installed on the environment- xml. My macmini needs to be installed with brew. I haven’t used brew for a long time. Brew update is extremely slow. According to Baidu’s post, I replaced the link to Alibaba Cloud.

The result still doesn’t work. I brewed it for several hours. I don’t know how I found out later that namespace was used in tp6, so when using SimpleXMLElement, you have to write the following statement at the beginning of the file

use SimpleXMLElement;

How about TP6 Print the log to the log file

Because I interact with the WeChat official account, I don’t know how to facilitate debugging. I tried the interface debugging tool provided by WeChat, but it can only check whether the parameter settings are correct. So I used the stupidest method of printing logs.

To print logs, you need to make the following settings in TP6:

In config/log.php

1. Set the logging level

'level' => [' emergency'],

I wrote almost all level values ​​here when debugging.

1. Set the log saving directory

'path' => App()->getRuntimePath() .'/log',2. Then use the following in the program The statements are written to the log file in real time

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

After following the test public account, enter 999 to receive a normal reply. Enter 1 and the program will exit

This problem stuck with me for most of the day! !

At first, I thought there was a problem with the response returned to the WeChat platform, because I printed a lot of logs in ThinkWechat.php and found that as long as I entered information other than 999, the data2xml method could not be fully executed. , the log cannot be printed after


$node = dom_import_simplexml($child);.

I always thought it was

$node->appendChild($node->ownerDocument->createCDATASection($value));There was a problem with the execution of this code.
Therefore, I also found from the book "WeChat Public Platform Development" that the response xml is generated by setting the xml template and replacing the variables in the template with the sprintf method.

The result of this is that I can see in the log that the response xml was successfully generated, but entering 1 still did not get the response I expected. It should be that there is no response, and it displays "This official account is temporarily unable to provide services." , please try again later", and the program also exited immediately.

Later I discovered that if I randomly wrote a program, such as a public account that responded to the information entered by the user every time, like a response bucket, there would be no problems and the program would not exit. I suddenly wondered if it might be related to session? Because session is used in the source code to implement user registration and login.

I looked at the development documentation of TP6, and sure enough, it says that the session is not initialized by default. I feel like crying here.

According to the documentation, I opened the session:

1. Remove the comment

\think\middleware\SessionInit::class in app/middleware.php.

2. And remove session_start() in the code. Because TP6 only supports operating sessions through Session class methods and session helper functions. It does not support all session_xx functions.

After the Session is opened, the program will no longer exit. But a new problem occurred. After entering 999, enter 1. The official account responded correctly. Please enter the user name, but the reply after entering the user name was the same as entering 999. When prompted, enter 1 to register and enter 2 to log in. The correct one should be to prompt for a username.

At this time, I found that multiple session files were generated in the runtime/session directory. For the same user, there should be only one session file that is correct. It is equivalent to a new session file being generated every time the user interacts with the official account, so that the information previously entered by the user cannot be obtained.

Baidu later discovered that the reason for this is that

session is stored on the server side, so to distinguish each user's session, you need to use the client's cookie. The WeChat server does not send cookies to the developer server. Therefore, cookie-based sessions cannot be used.
But as long as a unique session_id is set for each user, the same effect can be achieved.
Everyone's WeChat ID is unique, so we can use WeChat ID as the user's session_id, or we can use it after md5 encryption.

I plan to use the value of FromUserName as the sessionid. That is, each user's own openid. However, TP6 does not support the session_id() method to set the sessionid. I later read the documentation and found that Session::setId can be used to set the SessionID, but I don't know why a different sessionID is still generated every time.

It says on the Internet that you can use openid. I found that every time the URL sent by the WeChat public account to the server does come with openid, I configured openid in session.php, hoping that TP6 will use the openid in the request every time. as sessionid. But it still didn't take effect.

TP6's session.php has the following configuration:

SESSION_ID submission variable to solve flash upload cross-domain
'var_session_id' => 'openid',

Checked the setId of the framework, the original code is as follows

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

It turns out that the sessionid must be a 32-bit string containing alphanumeric characters. If it does not meet the requirements (openid length is 28 bits), use The current time is used as the sessionid, so I changed the setId to the following, and then printed the sessionid in the index method, and found that it is the same every time.

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());
    }

Run the program and everything works fine. It feels great.

At this time, I think that all the problems I encountered before should have nothing to do with xml response. So I used the previous ThinkWechat.php, but found that the session file was not generated in the runtime/session directory.

After checking, I found that the response method of the original ThinkWechat.php ended with

exit($xml->asXML());

The TP6 official document has the following reminder:

Note that the operation of writing data to the Session will be localized and stored uniformly at the end of the request, so do not use exit and other interrupt operations after writing the Session data, which may This will cause the Session to not be written normally.

So I changed the exit statement to return $xml->asXML(); At this time, the session file is generated normally, and the information replied by the official account is also correct.

PS code has been hosted on github

https://github.com/sarawang9012/thinkwechat

Related recommendations: The latest 10 thinkphp video tutorials

The above is the detailed content of Detailed explanation of how to introduce ThinkWechat.php in TP and print logs. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete