#php #session
#php #сеанс
Вопрос:
Я запустил тот же сеанс в DB и отлично работает, чтобы пользователь входил в систему дольше, чем время по умолчанию из php.ini.
Я понял две вещи, и я пока не мог это исправить
Сбор мусора не работает с функцией session_handler
И если я использую эту функцию unset ($_session[«var»]), поле данных по-прежнему содержит имя переменной сеанса и то же значение.
Мой вопрос:
Как я могу удалить значение из поля данных?
Как исправить сборку мусора, чтобы удалить строку через 30 минут? (поскольку это не удаление)
это мой код session_handler:
CREATE TABLE IF NOT EXISTS `sessions` (
`session_id` char(32) NOT NULL,
`last_update` datetime DEFAULT NULL,
`session_data` longtext,
PRIMARY KEY (`session_id`)
)
$sdbc = NULL;
/*** Open Session ***/
function _Session_Open()
{
global $sdbc;
$db = 'dataBase';
$us = 'user';
$pw = 'password';
// Connect to the database.
$sdbc = mysqli_connect('host',$us, $pw, $db) or die ('Error: ' . mysqli_error());
return true;
} // end of _Session_Open
/*** Close Session ***/
function _Session_Close()
{
global $sdbc;
return mysqli_close($sdbc);
} // end of _Session_Close
/*** Read Session ***/
function _Session_Read($sid)
{
global $sdbc;
$now = date("Y-m-d H:i:s");
$sid = mysqli_real_escape_string($sdbc, $sid);
$sql = " SELECT session_data FROM sessions WHERE session_id = '$sid' ";
$row = mysqli_query($sdbc, $sql) or die ('Line 49 ' .mysqli_error());
// Retrieve the results:
if (mysqli_num_rows($row) == 1)
{
list($data) = mysqli_fetch_array($row, MYSQLI_NUM);
// Return the data:
return $data;
} else { // Return an empty string.
return '';
}
/*** clear variables ***/
unset($now, $sid, $sql, $row, $data);
} // end of _Session_Read
/*** Write Session ***/
function _Session_Write($sid, $sdata)
{
global $sdbc;
$now = date("Y-m-d H:i:s");
$sid = mysqli_real_escape_string($sdbc, $sid);
$sdata = mysqli_real_escape_string($sdbc, $sdata);
$sql = " REPLACE INTO sessions
(session_id, last_update, session_data)
VALUES
('$sid', '$now','$sdata')
";
$row = mysqli_query($sdbc, $sql) or die ('Line 86 ' .mysqli_error());
return mysqli_affected_rows($sdbc);
/*** clear variables ***/
unset($now, $sid, $sql, $row, $data);
} // end of _Session_Write
/*** Destroy Session ***/
function _Session_Destroy($sid)
{
global $sdbc;
$sql = "DELETE FROM sessions WHERE session_id = '$sid'";
$row = mysqli_query($sdbc, $sql) or die ('Line 104 ' .mysqli_error());
return mysqli_affected_rows($sdbc);
/*** clear variables ***/
unset($sid, $sql, $row);
} // end of _Session_Destroy
/*** Garbagge Collector ***/
function _Session_GC($maxlifetime)
{
global $sdbc;
$yesterday = date("Y-m-d H:i:s", time() - 60*270);
$sql = "DELETE FROM sessions WHERE last_update < '$yesterday' ";
$row = mysqli_query($sdbc, $sql) or die ('Line 124 ' .mysqli_error());
return mysqli_affected_rows($sdbc);
/*** clear variables ***/
unset($yesterday, $sql, $row);
}
/* Register the session handling functions with PHP. */
session_set_save_handler(
'_Session_Open',
'_Session_Close',
'_Session_Read',
'_Session_Write',
'_Session_Destroy',
'_Session_GC'
);
session_start();
Комментарии:
1. Просто примечание: вместо ‘Line 86’, ‘Line 104’ и т.д., Вас может заинтересовать
__LINE__
константа PHP.2. Спасибо, мудрец, я воспользовался твоим предложением.
Ответ №1:
У вас есть несколько вызовов unset() после возврата из функций.
Примеры:
if (mysqli_num_rows($row) == 1)
{
list($data) = mysqli_fetch_array($row, MYSQLI_NUM);
// Return the data:
return $data;
} else { // Return an empty string.
return '';
}
// WON'T REACH THIS CODE
/*** clear variables ***/
unset($now, $sid, $sql, $row, $data);
и
return mysqli_affected_rows($sdbc);
/*** clear variables ***/
unset($now, $sid, $sql, $row, $data);
Исправить:
$result = ... ;
unset ( ... );
return $result;
Комментарии:
1. Я понял, спасибо, Jcinacio, я исправил эту часть. Но у меня все еще есть проблема с отключением сеанса. Имя и значение не были удалены из поля данных в базе данных.
2. Из комментариев в руководстве по session_set_save_handler, я считаю, что вам нужно явно вызвать
register_shutdown_function('session_write_close');
Ответ №2:
Я решил одну проблему
Я вызывал session_write_close(); каждый раз, когда я читал, добавлял или изменял значения переменных сеанса.
итак, теперь я вызываю session_write_close (); один раз в конце моего скрипта и работает идеально.
Но я не смог разрешить сборку мусора, чтобы удалить строку через 30 минут.