Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Проблема с видимостью глобальных переменных в callback-функции
Форумы портала PHP.SU » » Если скрипт не работает » Проблема с видимостью глобальных переменных в callback-функции

Страниц (1): [1]
 

1. DeNCHiK01 - 13 Февраля, 2015 - 19:28:38 - перейти к сообщению
Добрый вечер!

Возникла проблема следующего характера:
Пробую перевести сессии на хранение в БД.
Существует класс Sessions, содержащий функции по работе с ними.
PHP:
скопировать код в буфер обмена
  1. function initialize()
  2. {
  3.         session_set_save_handler(array($this,"sess_open"), array($this,"sess_close"), array($this,"sess_read"), array($this,"sess_write"), array($this,"sess_destroy"), array($this,"sess_gc"));
  4.         session_set_cookie_params(SECURITY_EXPIRE);
  5.         session_start();
  6. }

Соответственно указывают имена функций и $this, т.к. находятся они в этом же классе.
PHP:
скопировать код в буфер обмена
  1. function sess_write($key, $val)
  2.         {
  3.                 global $db; // PDO
  4.                 global $tbl_sess; // Название таблицы
  5.                 global $utils; // Класс утилит
  6.                 echo $tbl_sess; // testuser_sessions
  7.                 if($utils != "") echo "UTILS!<br/>";
  8.                 if($db != "") echo "WORKIIIIIIIIIIING!<br/>";
  9.                 $query = $db->prepare(...);
  10.                 $query->execute();
  11.         }

В функции записи сессии пытаюсь использовать глобальные переменные $db(PDO), $tbl_sess(название таблицы) и $utils(класс утилит).
Собственно, если вызывать функцию напрямую из любой точки скрипта, то все работает, но когда функция вызывается коллбэком параметры $utils и $db пусты, $tbl_sess выдается.
Ну и соответственно выдает ошибку Fatal error: Call to a member function prepare() on a non-object in .../functions.php on line 150
Не подскажите, что делать в данной ситуации?
2. Ch_chov - 13 Февраля, 2015 - 19:45:23 - перейти к сообщению
DeNCHiK01 пишет:
Не подскажите, что делать в данной ситуации?
Отладку. Возможно эти переменные еще не инициализированные в этот момент.
3. DeNCHiK01 - 13 Февраля, 2015 - 20:43:59 - перейти к сообщению
Проверил это сразу. По идее все есть и по логике кода + напрямую функцию sess_write вызываю еще до initialize и все работает.
4. Bio man - 13 Февраля, 2015 - 21:58:27 - перейти к сообщению
global? Глобальные переменные - зло, использовать классы ради классов - тоже зло.
Глобальные объекты не видны, по той причине, что коллбек write вызывается после уничтожения объектов.
Вот, почитай https://bugs.php.net/bug.php?id=50154
Решение - вызывать session_write_close из деструктора.
5. DeNCHiK01 - 16 Февраля, 2015 - 07:26:12 - перейти к сообщению
Добавил вызов из деструктора, если я, конечно, все правильно сделал, но проблема осталась
PHP:
скопировать код в буфер обмена
  1.  
  2. function __destruct()
  3.         {
  4.                 echo "destruct<br/>";
  5.                 session_write_close();
  6.                 echo "destruct2<br/>";
  7.         }
  8.  


Вывод:
destruct
testuser_sessions
Fatal error: Call to a member function prepare() on a non-object in .../functions.php on line 150
destruct2
6. exlant - 16 Февраля, 2015 - 21:32:28 - перейти к сообщению
Если это при вызове bind_param(), то в mysqli есть оговорка по ее использованию! Не исключено, что в PDO может быть также... Хотя в документации не нашел!

Цитата:

При использовании mysqli_stmt_bind_param() совместно с call_user_func_array() необходимо соблюдать особую осторожность. Нужно принимать во внимание, что mysqli_stmt_bind_param() принимает в качестве параметров только ссылки на значения, в то время как call_user_func_array() принимает список параметров, которые могут передаваться как по ссылке, так и по значению.


У меня была похожая проблема, и ошибка такая же выводилась с колбэк функцией, только в mysqli c bind_param. Решил вот такой вот затычкой
PHP:
скопировать код в буфер обмена
  1.  
  2. function refValues($arr){
  3.         if (strnatcmp(phpversion(),'5.3') >= 0) { //Если версия PHP >=5.3 (в младших версиях все проще)
  4.                 $refs = array();
  5.                 foreach($arr as $key => $value) {
  6.                         $refs[$key] = &$arr[$key]; //Массиву $refs присваиваются ссылки на значения массива $arr
  7.                 }
  8.                 return $refs; //Массиву $arr присваиваются значения массива $refs
  9.         }
  10.         return $arr; //Возвращается массив $arr
  11.     }
  12. //вызываю так
  13. call_user_func_array(array($stmt,'bind_param'), $this->refValues($array));
  14.  

(Добавление)
Bio man пишет:
использовать классы ради классов - тоже зло.

А учиться же надо как то! Вот и используешь классы ради классов! А понимание приходит спустя время, и с опытом!
7. DeNCHiK01 - 16 Февраля, 2015 - 23:42:26 - перейти к сообщению
exlant,
Если я все правильно понял, то ваш вариант мне не подойдет, т.к. в
PHP:
скопировать код в буфер обмена
  1. call_user_func_array(array($stmt,'bind_param'), $this->refValues($array));

вы передаете параметры(refValues($array)).
В моем же случае коллбэк я устанавливаю через session_set_save_handler
PHP:
скопировать код в буфер обмена
  1. session_set_save_handler(array($this,"sess_open"), array($this,"sess_close"), array($this,"sess_read"), array($this,"sess_write"), array($this,"sess_destroy"), array($this,"sess_gc"));

А в ней параметры к функциям не передать, т.к. указываются лишь имена, а аргументы передаются автоматически нужные.

Но я не уверен на 100%, пожалуйста, поправьте меня, если не прав.
8. Bio man - 17 Февраля, 2015 - 13:38:53 - перейти к сообщению
DeNCHiK01, попробуй альтернативную декларацию session_set_save_handler, через интерфейс.
(Добавление)
на php.su устаревшая документация. http://php.net/manual/en/functio...save-handler.php
9. DeNCHiK01 - 17 Февраля, 2015 - 18:31:56 - перейти к сообщению
Bio man пишет:
DeNCHiK01, попробуй альтернативную декларацию session_set_save_handler, через интерфейс.
(Добавление)
на php.su устаревшая документация. http://php.net/manual/en/function.session-set-save-handler.php


Доступно только на 5.4+, у меня стоит 5.3.3. Стоит обновлять?
10. Bio man - 17 Февраля, 2015 - 19:51:28 - перейти к сообщению
DeNCHiK01 пишет:
Стоит обновлять?
читай чейнджлог, если будут изменения без обратной совместимости, и если проект большой, то лучше не стоит.
Если проект небольшой и обнаружатся какие то несовместимости, то их можно быстро поправить.

5.3 версия умерла, она официально не поддерживается, скоро с 5.4 случится тоже самое.
Так что лучше идти в ногу со временем.
11. DeNCHiK01 - 17 Февраля, 2015 - 20:26:30 - перейти к сообщению
Bio man пишет:
DeNCHiK01 пишет:
Стоит обновлять?
читай чейнджлог, если будут изменения без обратной совместимости, и если проект большой, то лучше не стоит.
Если проект небольшой и обнаружатся какие то несовместимости, то их можно быстро поправить.

5.3 версия умерла, она официально не поддерживается, скоро с 5.4 случится тоже самое.
Так что лучше идти в ногу со временем.


Как раз проект еще не слишком большой, противоречий не нашел в чейнджлоге.
На какую версию лучше перейти? 5.6.5?
12. Bio man - 17 Февраля, 2015 - 22:26:02 - перейти к сообщению
5.5 или 5.6.
5.4 тоже подойдёт

 

Powered by ExBB FM 1.0 RC1