📜 ⬆️ ⬇️

We write our implementation of sessions to handle a dead session before stripping.

My first habratopik, I hope that not the last.

Imagine a situation: there is a shopping cart on the site; when added to the cart, we put a so-called product on it. lock, excluding it from the list of products available for purchase. When a customer removes an item from the cart, the lock is removed. But what if the user simply closed the browser? In this case, the session will be deleted by the garbage collector, and the locks will remain.

When I faced such a situation, the first thing that occurred to me was to keep the locks and the date of access to the database and periodically pull it with a crown. But the crutch of this solution is obvious. And here's another nonsense that I encountered when solving a subject: for serialization and deserialization of sessions, functions and formats other than the functions serialize and unserialize are used. You have to make bikes for the session sequencing.
')
Closer to the body: how did I solve the problem ...
Here it is necessary to make a remark that the idea for this solution was given to me by a rigid browser, and they helped to solve a couple of near-sabzhevyh problems in the conference php@conference.jabber.ru.

PHP allows you to define your own functions for processing sessions. The session_set_save_handler function is responsible for this. As parameters, it takes a list of functions that will be called to work with sessions. The manual is even an example that implements the standard mechanism for working with sessions. We will take it by changing only the function gc, which deals with garbage collection, i.e. deleting dead session files.

An example of the gc function:

/* */
function gc($maxlifetime)
{
global $sess_save_path; /* , */
foreach (glob( "$sess_save_path/sess_*" ) as $filename)
{
/* */
if (filemtime($filename) + $maxlifetime < time())
{
$tmp_sess=unserializesession(file_get_contents($filename)); /* $tmp_sess $_SESSION */
/* , */
@unlink($filename); /* */
}
}
return true ;
}


* This source code was highlighted with Source Code Highlighter .


The function code unserializesession, taken from somewhere on the Internet (most likely from the comments to the function in the PHP manual):

function unserializesession($data) {
$vars=preg_split( '/([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff^|]*)\|/' ,
$data,-1,PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
for ($i=0; $vars[$i]; $i++) $result[$vars[$i++]]=unserialize($vars[$i]);
return $result;
}


* This source code was highlighted with Source Code Highlighter .


Now we connect it to our project:

session_set_save_handler( "open" , "close" , "read" , "write" , "destroy" , "gc" );
/* session_start() 30%, - session_start() */
ini_set( "session.gc_probability" , 30); /* 100%, */
ini_set( "session.gc_divisor" , 100);
ini_set( "session.gc_maxlifetime" , 1800); /* ( , gc) */
session_start();


* This source code was highlighted with Source Code Highlighter .


There is one thing: in Debian / Ubuntu its own session cleaning mechanism, which is executed by crown, while PHP does not have the ability to delete session files. I did not like it, because breaks PHP functionality by replacing it with its session garbage collector. You can solve the problem by setting your own directory for session files and closing it in .htaccess (if it is in document_root).

PS Honestly, I'm not sure that I could post a post immediately to the PHP blog. I am not an active user of Habr and do not know the local order. Please do not swear.

Source: https://habr.com/ru/post/78774/


All Articles