PDA

Просмотр полной версии : Обьект уничтожается раньше времени


Doom123
16.05.2009, 11:39
возникла проблема ... у меня есть класс для работы с сессиями через БД потом от нех делать рнешил сделать тоже самое но с использованием

session_set_save_handler

вот что я делаю ..


<?php

//Различные функции
require_once ('includes/func.php');
//Файл конфигурации\\
require_once ('includes/config.php');

$a = 'aa';

function ses_open($save_path,$ses_name) {
return true; }
function ses_close() { return true; }

function ses_read($key)
{
global $db;
$res = $db->mysql_qw('SELECT `val` FROM `session` WHERE `key`=?',$key) or die();
$fetch = $db->mysql_fetch($res);

return $fetch['val'];
}

function ses_write($key,$val)
{
global $db;

$db->mysql_qw('REPLACE INTO `session` SET `val`=?,`key`=?',$val,$key) or die();

return true;
}

function ses_destroy($key)
{
global $db;
$db->mysql_qw('DELETE FROM `session` WHERE `key` = ?',$key) or die();
return true;
}

function ses_gc($maxlifetime)
{
global $db;
$time = time() - $maxlifetime;
$db->mysql_qw('DELETE FROM `session` WHERE UNIX_TIMESTAMP(`time`) <= ?',$time) or die();
return true;
}


session_set_save_handler("ses_open","ses_close","ses_read","ses_write","ses_destroy","ses_gc");




session_start();

$_SESSION['test'] = 1;

?>


Выводит ошибку

Fatal error: Call to a member function mysql_qw() on a non-object in test.php on line 29

Я сделал вывод массива $GLOBALS в ф-ции ses_read и ses_write

И удивился когда обьект $db существует в ses_read

а в ses_write он уже уничтожен ... думал изза
__destruct() в классе mysql но нет =\\


кто может обьеснить что тут произошло?

Gifts
16.05.2009, 12:33
Doom123, В мануале все написано, в общем-то

As of PHP 5.0.5 the write and close handlers are called after object destruction and therefore cannot use objects or throw exceptions. The object destructors can however use sessions.

It is possible to call session_write_close() from the destructor to solve this chicken and egg problem.

Плюс к этому комментарий:

If using mysqli in procedural style you may expect the mysqli handle to be valid in the write callback. It is not the case, the handle in procedural style is a object that will be destroy unlink the plain mysql interface handle. Just register a shutdown function after set save handler like this:

session_set_save_handler('_session_open', '_session_close', '_session_read', '_session_write', '_session_destroy', '_session_gc');
register_shutdown_function('session_write_close');

Pashkela
16.05.2009, 12:46
Может из-за этого:

session_write_close(); //cancel the session's auto start,important

Прописать в самом начале

Doom123
16.05.2009, 13:01
Gifts значит вызов записи и закрытия происходят после уничтожения обьектов?
а насчёт session_write_close я так и не понел чтоб решить эту проблему можно вызвать из деструктора эту функцию?

Doom123
16.05.2009, 13:14
хех ... ппц )) вызвал ф-цию в деструкторе ... тож не работает но только теперь при выводе масива GLOBALS выводит


Array
*RECURSION*

Gifts
16.05.2009, 13:41
Doom123 Функция session_write_close должна быть вызвана последней, или после всех операций с сессиями. Или можно зарегистрировать, чтобы функция вызывалась перед завершением скрипта, с помощью register_shutdown_function('session_write_close');

Если же просто ждать когда сработает session_set_save_handler то все объекты будут уже разрушены.