A known useful method is to use session_set_save_handler to take over all session management work. Generally, session information is stored in the database, so that all expired sessions can be deleted through SQL statements and precisely controlled the validity period of the session. This is also a common method for large websites based on PHP. However, it seems that there is no need for ordinary small websites to mobilize so many people.
However, the life of a general session is limited. If the user closes the browser, the session variable cannot be saved! So how can we achieve the permanent life of Session?
As we all know, the Session is stored on the server side. The user's file is obtained based on the SessionID provided by the client, and then the file is read and the value of the variable is obtained. The SessionID can be transmitted to the server using the client's cookie or the Query_String of the Http1.1 protocol (that is the part after the URL "?") and the server reads the Session directory...
To implement the permanent life of a Session, you need to first understand the relevant settings for Session (open the file, in the "[Session]" section):
1. session.use_cookies: The default value is "1", which means that SessionID uses cookies to pass, otherwise it is to pass using Query_String;
2.: This is the variable name stored in SessionID, which may be a cookie or a Query_String. The default value is "PHPSESSID";
3. session.cookie_lifetime: This represents the time when SessionID is stored in the client cookie. The default is 0, which means that the browser will be invalidated once the SessionID is closed... It is because of this that Session cannot be used permanently!
4. session.gc_maxlifetime: This is the time when Session data is stored on the server side. If this time exceeds this time, the Session data will be automatically deleted!
There are many settings, but these are all related to this article. Let’s start with the principles and steps of using permanent sessions.
As mentioned earlier, the server reads the Session data through the SessionID, but the SessionID sent by the browser will disappear after the browser is closed. So we only need to set the SessionID manually and save it, so we can...
If you have the operation permissions of the server, then setting this is very, very simple, just need to go through the following steps:
1. Set "session.use_cookies" to 1, turn on the cookie to store the SessionID, but the default is 1, and generally no need to modify it;
2. Change "session.cookie_lifetime" to positive infinite (of course there is no parameter for positive infinite, but there is no difference between 9999999999 and positive infinite);
3. Set "session.gc_maxlifetime" to the same time as "session.cookie_lifetime";
In PHP's documentation, it is clearly stated that the parameter that sets the validity period of the session is session.gc_maxlifetime. This parameter can be modified in the file or through the ini_set() function. The problem is that after multiple tests, modifying this parameter basically does not work, and the session validity period remains at the default value of 24 minutes.
Due to PHP's working mechanism, it does not have a daemon thread to scan the session information regularly and determine whether it is invalid. When a valid request occurs, PHP will decide whether to start a GC (Garbage Collector) based on the value of the global variable session.gc_probability/session.gc_divisor (which can also be modified by the ini_set() function). By default, session.gc_probability = 1, session.gc_divisor = 100, which means there is a 1% chance that GC will be started.
The job of GC is to scan all session information, subtract the session's last modified date with the current time, and compare it with the session.gc_maxlifetime parameter. If the survival time has exceeded gc_maxlifetime, the session will be deleted.
So far, everything worked fine. Then why does gc_maxlifetime invalid happen?
By default, session information is saved in the system's temporary file directory as a text file. In Linux, this path is usually \tmp, and in Windows it is usually C:\Windows\Temp. When there are multiple PHP applications on the server, they will save their session files in the same directory. Similarly, these PHP applications will also start GC with a certain chance to scan all session files.
The problem is that when GC works, it does not distinguish between sessions of different sites. For example, the gc_maxlifetime of site A is set to 2 hours, and the gc_maxlifetime of site B is set to the default 24 minutes. When the GC of Site B starts, it scans the public temporary file directory and deletes all session files that have been over 24 minutes, regardless of whether they come from Site A or B. In this way, the gc_maxlifetime setting of site A is useless.
Finding the problem is very easy to solve. Modify the session.save_path parameter, or use the session_save_path() function to point the directory where the session is saved to a dedicated directory. The gc_maxlifetime parameter works normally.
Strictly speaking, this is a bug in PHP?
Another problem is that gc_maxlifetime can only ensure the shortest time of the session survival, and cannot be saved after this time, the session information will be deleted immediately. Because GC is started at a probability and may not be started for a long time, a large number of sessions will still be valid after exceeding gc_maxlifetime. One way to solve this problem is to increase the chance of session.gc_probability/session.gc_divisor. If 100% is mentioned, this problem will be completely solved, but it will obviously have a serious impact on performance. Another method is to judge the survival time of the current session in the code yourself. If gc_maxlifetime is exceeded, clear the current session.
However, if you do not have server operation permissions, it will be more troublesome. You need to rewrite the SessionID through a PHP program to achieve permanent Session data storage. Check the function manual and you can see the function "session_id": If no parameter is set, the current SessionID will be returned. If the parameter is set, the current SessionID will be set to the given value...
Just use the permanent cookie plus the "session_id" function to save permanent Session data!
However, for convenience, we need to know the "" set by the server, but most users do not have permission to view the server settings. However, PHP provides a very good function "phpinfo", which can use this to view almost all PHP information!
------------------------------------------------------------------------------------
<title>PHP related information display</title>
<?phpinfo()?>
------------------------------------------------------------------------------------
Open the editor, enter the code above, and then run the program in the browser, and you will see PHP related information (as shown in Figure 1). There is one parameter of "", which is the server "" we need, which is generally "PHPSESSID".
After writing down the SessionID name, we can implement permanent Session data storage!
session_start();
ini_set('session.save_path','/tmp/');
//6 hours
ini_set('session.gc_maxlifetime',21600);
//Save for one day
$lifeTime = 24 * 3600;
setcookie(session_name(), session_id(), time() + $lifeTime, "/");
postscript:
In fact, true permanent storage is impossible, because the storage time of cookies is limited and the space of the server is limited... But for some sites that require a longer storage time, the above method is enough!
Put session into mysql's Example:
Create tables in the database: session (sesskey varchar32, expiry int11, value longtext)
code:
The database has been connected before the code is executed.
define('STORE_SESSIONS','mysql');
if (STORE_SESSIONS == 'mysql') {
if (!$SESS_LIFE = get_cfg_var('session.gc_maxlifetime')) {
$SESS_LIFE = 1440;
}
function _sess_open($save_path, $session_name) {
// If the database is not connected, you can execute mysql_pconnect,mysql_select_db here
return true;
}
function _sess_close() {
return true;
}
function _sess_read($key) {
$value_query = mysql_query("select value from sessions where sesskey = '" .addslashes($key) . "' and expiry > '" . time() . "'");
$value = mysql_fetch_array($value_query);
if (isset($value['value'])) {
return $value['value'];
}
return false;
}
function _sess_write($key, $val) {
global $SESS_LIFE;
$expiry = time() + $SESS_LIFE;
$value = $val;
$check_query = mysql_query("select count(*) as total from sessions where sesskey = '" . addslashes($key) . "'");
$check = mysql_fetch_array($check_query);
if ($check['total'] > 0) {
return mysql_query("update sessions set expiry = '" . addslashes($expiry) . "', value = '" . addslashes($value) . "' where sesskey = '" . addslashes($key) . "'");
} else {
return mysql_query("insert into sessions values ('" . addslashes($key) . "', '" . addslashes($expiry) . "', '" . addslashes($value) . "')");
}
}
function _sess_destroy($key) {
return mysql_query("delete from sessions where sesskey = '" . addslashes($key) . "'");
}
function _sess_gc($maxlifetime) {
mysql_query("delete from sessions where expiry < '" . time() . "'");
return true;
}
session_set_save_handler('_sess_open', '_sess_close', '_sess_read', '_sess_write', '_sess_destroy', '_sess_gc');
}
danoo_session_name( 'dtvSid' );
danoo_session_save_path(SESSION_WRITE_DIRECTORY);
I still don’t understand where the parameters of open and write come from.
Two common functions for modifying configuration:
get_cfg_var('session.gc_maxlifetime') : Get the value of session.gc_maxlifetime
ini_set('session.cookie_lifetime','0') : Sets the value of session.cookie_lifetime to 0.
However, the life of a general session is limited. If the user closes the browser, the session variable cannot be saved! So how can we achieve the permanent life of Session?
As we all know, the Session is stored on the server side. The user's file is obtained based on the SessionID provided by the client, and then the file is read and the value of the variable is obtained. The SessionID can be transmitted to the server using the client's cookie or the Query_String of the Http1.1 protocol (that is the part after the URL "?") and the server reads the Session directory...
To implement the permanent life of a Session, you need to first understand the relevant settings for Session (open the file, in the "[Session]" section):
1. session.use_cookies: The default value is "1", which means that SessionID uses cookies to pass, otherwise it is to pass using Query_String;
2.: This is the variable name stored in SessionID, which may be a cookie or a Query_String. The default value is "PHPSESSID";
3. session.cookie_lifetime: This represents the time when SessionID is stored in the client cookie. The default is 0, which means that the browser will be invalidated once the SessionID is closed... It is because of this that Session cannot be used permanently!
4. session.gc_maxlifetime: This is the time when Session data is stored on the server side. If this time exceeds this time, the Session data will be automatically deleted!
There are many settings, but these are all related to this article. Let’s start with the principles and steps of using permanent sessions.
As mentioned earlier, the server reads the Session data through the SessionID, but the SessionID sent by the browser will disappear after the browser is closed. So we only need to set the SessionID manually and save it, so we can...
If you have the operation permissions of the server, then setting this is very, very simple, just need to go through the following steps:
1. Set "session.use_cookies" to 1, turn on the cookie to store the SessionID, but the default is 1, and generally no need to modify it;
2. Change "session.cookie_lifetime" to positive infinite (of course there is no parameter for positive infinite, but there is no difference between 9999999999 and positive infinite);
3. Set "session.gc_maxlifetime" to the same time as "session.cookie_lifetime";
In PHP's documentation, it is clearly stated that the parameter that sets the validity period of the session is session.gc_maxlifetime. This parameter can be modified in the file or through the ini_set() function. The problem is that after multiple tests, modifying this parameter basically does not work, and the session validity period remains at the default value of 24 minutes.
Due to PHP's working mechanism, it does not have a daemon thread to scan the session information regularly and determine whether it is invalid. When a valid request occurs, PHP will decide whether to start a GC (Garbage Collector) based on the value of the global variable session.gc_probability/session.gc_divisor (which can also be modified by the ini_set() function). By default, session.gc_probability = 1, session.gc_divisor = 100, which means there is a 1% chance that GC will be started.
The job of GC is to scan all session information, subtract the session's last modified date with the current time, and compare it with the session.gc_maxlifetime parameter. If the survival time has exceeded gc_maxlifetime, the session will be deleted.
So far, everything worked fine. Then why does gc_maxlifetime invalid happen?
By default, session information is saved in the system's temporary file directory as a text file. In Linux, this path is usually \tmp, and in Windows it is usually C:\Windows\Temp. When there are multiple PHP applications on the server, they will save their session files in the same directory. Similarly, these PHP applications will also start GC with a certain chance to scan all session files.
The problem is that when GC works, it does not distinguish between sessions of different sites. For example, the gc_maxlifetime of site A is set to 2 hours, and the gc_maxlifetime of site B is set to the default 24 minutes. When the GC of Site B starts, it scans the public temporary file directory and deletes all session files that have been over 24 minutes, regardless of whether they come from Site A or B. In this way, the gc_maxlifetime setting of site A is useless.
Finding the problem is very easy to solve. Modify the session.save_path parameter, or use the session_save_path() function to point the directory where the session is saved to a dedicated directory. The gc_maxlifetime parameter works normally.
Strictly speaking, this is a bug in PHP?
Another problem is that gc_maxlifetime can only ensure the shortest time of the session survival, and cannot be saved after this time, the session information will be deleted immediately. Because GC is started at a probability and may not be started for a long time, a large number of sessions will still be valid after exceeding gc_maxlifetime. One way to solve this problem is to increase the chance of session.gc_probability/session.gc_divisor. If 100% is mentioned, this problem will be completely solved, but it will obviously have a serious impact on performance. Another method is to judge the survival time of the current session in the code yourself. If gc_maxlifetime is exceeded, clear the current session.
However, if you do not have server operation permissions, it will be more troublesome. You need to rewrite the SessionID through a PHP program to achieve permanent Session data storage. Check the function manual and you can see the function "session_id": If no parameter is set, the current SessionID will be returned. If the parameter is set, the current SessionID will be set to the given value...
Just use the permanent cookie plus the "session_id" function to save permanent Session data!
However, for convenience, we need to know the "" set by the server, but most users do not have permission to view the server settings. However, PHP provides a very good function "phpinfo", which can use this to view almost all PHP information!
------------------------------------------------------------------------------------
<title>PHP related information display</title>
<?phpinfo()?>
------------------------------------------------------------------------------------
Open the editor, enter the code above, and then run the program in the browser, and you will see PHP related information (as shown in Figure 1). There is one parameter of "", which is the server "" we need, which is generally "PHPSESSID".
After writing down the SessionID name, we can implement permanent Session data storage!
Copy the codeThe code is as follows:
session_start();
ini_set('session.save_path','/tmp/');
//6 hours
ini_set('session.gc_maxlifetime',21600);
//Save for one day
$lifeTime = 24 * 3600;
setcookie(session_name(), session_id(), time() + $lifeTime, "/");
postscript:
In fact, true permanent storage is impossible, because the storage time of cookies is limited and the space of the server is limited... But for some sites that require a longer storage time, the above method is enough!
Put session into mysql's Example:
Create tables in the database: session (sesskey varchar32, expiry int11, value longtext)
code:
The database has been connected before the code is executed.
Copy the codeThe code is as follows:
define('STORE_SESSIONS','mysql');
if (STORE_SESSIONS == 'mysql') {
if (!$SESS_LIFE = get_cfg_var('session.gc_maxlifetime')) {
$SESS_LIFE = 1440;
}
function _sess_open($save_path, $session_name) {
// If the database is not connected, you can execute mysql_pconnect,mysql_select_db here
return true;
}
function _sess_close() {
return true;
}
function _sess_read($key) {
$value_query = mysql_query("select value from sessions where sesskey = '" .addslashes($key) . "' and expiry > '" . time() . "'");
$value = mysql_fetch_array($value_query);
if (isset($value['value'])) {
return $value['value'];
}
return false;
}
function _sess_write($key, $val) {
global $SESS_LIFE;
$expiry = time() + $SESS_LIFE;
$value = $val;
$check_query = mysql_query("select count(*) as total from sessions where sesskey = '" . addslashes($key) . "'");
$check = mysql_fetch_array($check_query);
if ($check['total'] > 0) {
return mysql_query("update sessions set expiry = '" . addslashes($expiry) . "', value = '" . addslashes($value) . "' where sesskey = '" . addslashes($key) . "'");
} else {
return mysql_query("insert into sessions values ('" . addslashes($key) . "', '" . addslashes($expiry) . "', '" . addslashes($value) . "')");
}
}
function _sess_destroy($key) {
return mysql_query("delete from sessions where sesskey = '" . addslashes($key) . "'");
}
function _sess_gc($maxlifetime) {
mysql_query("delete from sessions where expiry < '" . time() . "'");
return true;
}
session_set_save_handler('_sess_open', '_sess_close', '_sess_read', '_sess_write', '_sess_destroy', '_sess_gc');
}
danoo_session_name( 'dtvSid' );
danoo_session_save_path(SESSION_WRITE_DIRECTORY);
I still don’t understand where the parameters of open and write come from.
Two common functions for modifying configuration:
get_cfg_var('session.gc_maxlifetime') : Get the value of session.gc_maxlifetime
ini_set('session.cookie_lifetime','0') : Sets the value of session.cookie_lifetime to 0.