Home >Backend Development >PHP Tutorial >Issues related to PHP Session validity period_PHP tutorial

Issues related to PHP Session validity period_PHP tutorial

WBOY
WBOYOriginal
2016-07-13 10:33:18933browse

Session processing is a problem that all web applications must face. The processing of session validity period in PHP is very different from other solutions. This is related to the working mechanism of PHP.

In traditional client/server applications, session failures can be handled by the network protocol itself. Whether the client actively closes the connection or the connection is interrupted due to network abnormalities, the server can be notified and trigger the connection interruption event. Just program to respond to this event and perform the specified operation. But for web applications, the situation is completely different. The HTTP protocol itself is stateless, that is to say, every time the client/server completes a request/response process, the connection will be disconnected. After disconnecting, the server does not know whether the client continues to be "online" and will continue to send the next request. In other words, no matter whether the user on the client side has closed the browser window, or the user is just reading the current web page and preparing to continue browsing in the next second, or the user is affected by Windows crash/power outage/hard drive failure/network cable being unplugged/the earth exploding. It is completely impossible to send the next request, and the server knows nothing about it. (In HTTP 1.1, the browser can use the keep-alive parameter to notify the server not to actively disconnect after responding to the request, thereby achieving a physical long connection. However, this is only a measure taken to improve the performance of network transmission. , HTTP is still logically stateless.) Therefore, it can only be determined through some simulation method whether the current session is valid. If a session does not make a request to the server after a period of time, the server will determine that the user is "offline", the current session will become invalid, and a connection interruption event will be triggered. To do this, the server needs to run a background thread to scan all session information regularly to determine whether the session has timed out.

The principle of PHP session processing is no exception, but the specific implementation method is different. This is because, due to the working mechanism of PHP, it does not have a background thread to regularly scan session information and determine whether it is invalid. The solution is that when a valid request occurs, PHP will decide whether to call a GC (Garbage Collector) based on a certain probability. The job of the GC is to scan all session information, subtract the last modification time (modified date) of the session from the current time, and compare it with the value of the configuration parameter (configuration option) session.gc_maxlifetime. If the survival time has exceeded gc_maxlifetime, The session is deleted. This is easy to understand, because if the GC code is called for every request, the efficiency of PHP will be unbearably low. This probability depends on the value of the configuration parameter session.gc_probability/session.gc_divisor (can be modified through the php.ini or ini_set() function). By default, session.gc_probability = 1, session.gc_divisor=100, which means there is a 1% probability that GC will be started. These three parameters, session.gc_maxlifetime/session.gc_probability/session.gc_divisor, can be modified through the php.ini or ini_set() function. But remember, if you use the ini_set() function, you must call ini_set() at the beginning of each page.

This leads to another problem. gc_maxlifetime can only guarantee the shortest time for the session to survive, and cannot be saved. After this time, the session information will be deleted immediately. Because GC is started based on probability and may not be started for a long period of time, a large number of sessions will still be valid after exceeding gc_maxlifetime. Of course, the probability of this happening is very small, but if your application requires very precise session expiration, this can cause serious problems. One way to solve this problem is to increase the probability of session.gc_probability/session.gc_divisor. If mentioned to 100%, this problem will be completely solved, but it will obviously have a serious impact on performance. Another method is to abandon PHP's GC and judge the current session's lifetime in the code. If it exceeds gc_maxlifetime, clear the current session.

The default session validity period in PHP is 1440 seconds (24 minutes). That is to say, if the client does not refresh for more than 24 minutes, the current session will expire. To modify this default value, the correct solution is to modify the configuration parameter session.gc_maxlifetime.

I once searched the Internet for solutions to this problem, and the results I found were all kinds of strange. Some people say that "session_life_time" should be set. As far as I know, there is no such parameter in PHP. Some say that you need to call session_set_cookie_params, or set session.cookie_lifetime, which is only used to set the lifetime of the cookie on the client side. In other words, modifying this value is only effective when the lifetime of the cookie on the client side is less than the session lifetime on the server side, and The longest duration cannot exceed the session lifetime on the server side. The reason is very simple. When the session on the server side has expired, it is meaningless no matter how long the lifetime of the client-side cookie is. Others say that session_cache_expire should be called. This parameter is used to notify the browser and proxy how long the content of the current page should be cached. It is not directly related to the lifetime of the session.

Sounds like this solution is perfect. However, when you try to modify the value of session.gc_maxlifetime in practice, you are likely to find that this parameter has basically no effect, and the session validity period remains at the default value of 24 minutes. It may even happen that it works fine in the development environment but not on the server!

In order to completely solve this problem, further analysis of the working details of PHP is required.

By default, session information in PHP will be saved in the system's temporary file directory in the form of text files. This path is specified by the configuration parameter session.save_path. Under Linux, this path is usually tmp, and under Windows, it is usually C:WindowsTemp. When there are multiple PHP applications on the server, they will save their session files in the same directory (because they use the same session.save_path parameter). Similarly, these PHP applications will also start GC at a certain probability and scan all session files.

The problem is that when GC is working, it does not distinguish between sessions on different sites. For example, site A's gc_maxlifetime is set to 2 hours, and site B's gc_maxlifetime is set to the default 24 minutes. When site B's GC starts, it will scan the public temporary file directory and delete all session files older than 24 minutes, regardless of whether they come from site A or B. In this way, the gc_maxlifetime setting of site A is useless.

Once you find the problem, it’s easy to solve it. Call the session_save_path() function at the beginning of the page, which can modify the session.save_path parameter and point the directory where the session is saved to a dedicated directory, such as tmpmyapp. In this way, the gc_maxlifetime parameter works normally.

Using a public session.save_path also leads to security issues, because it means that other PHP programs on the same server can also read your site's session file, which may be used for hacker attacks. Another problem is efficiency: in a busy site, there may be thousands of session files, and the session files of many different websites are placed in the same directory, whether it is reading and writing a single file, or traversing GC for all files will undoubtedly lead to a decrease in performance. Therefore, if your PHP application runs on the same server as other PHP applications, it is strongly recommended that you use your own session.save_path.

Strictly speaking, this is a bug in PHP. When PHP is doing GC, it should differentiate between session files from different sites and apply different gc_maxlifetime values. Currently, the latest PHP 5.2.X still has this problem.

As mentioned above, in a busy site, there may be thousands of session files. Even if the session.save_path directories of different sites are distinguished, the number of session files in a single site may still cause efficiency problems. In order to solve this problem, several possible methods are:

If PHP is running under a Linux system, use the ReiserFS file system instead of the default ext2/ext3 file system. ReiserFS's access performance for a large number of small files is greatly improved compared to ext2/ext3.

Point session.save_path to a memory path. This means that the reading and writing of the session file are only performed in memory and no disk operations are performed.

session.save_path accepts an additional N parameter to specify the level of the directory. For example, "5;/tmp" will result in the creation of a session file similar to: /tmp/4/b/1/e/3/sess_4b1e384ad74619bd212e236e52a5a174If. For specific instructions, please see: http://cn.php.net/manual/en/session.configuration.php#ini.session.save-path

The ultimate solution is to abandon PHP's session processing mechanism and code it yourself to take over all session processing operations, implemented through the session_set_save_handler() function. By taking over the session processing yourself, all sessions can be saved in a special database (often using a memory table), thereby completely solving the problems caused by session files, and allowing session sharing and copying to be easily achieved. This is also the method generally used by large PHP applications. Regarding the use of the session_set_save_handler() function, there are detailed instructions on the Internet and related books, so I will not go into details here. It is worth mentioning that even in this way, the probability of starting GC still depends on session.gc_probability/session.gc_divisor.

www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/752506.htmlTechArticleSession processing is a problem that all web applications must face. The processing of session validity period in PHP is very different from other solutions. This is related to the working mechanism of PHP...
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn