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

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

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


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

> Без описания
DeNCHiK01
Отправлено: 13 Февраля, 2015 - 19:28:38
Post Id


Новичок


Покинул форум
Сообщений всего: 10
Дата рег-ции: Февр. 2015  


Помог: 0 раз(а)




Добрый вечер!

Возникла проблема следующего характера:
Пробую перевести сессии на хранение в БД.
Существует класс 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
Не подскажите, что делать в данной ситуации?

(Отредактировано автором: 13 Февраля, 2015 - 19:30:16)

 
 Top
Ch_chov
Отправлено: 13 Февраля, 2015 - 19:45:23
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2121
Дата рег-ции: Июль 2008  
Откуда: из города


Помог: 90 раз(а)




DeNCHiK01 пишет:
Не подскажите, что делать в данной ситуации?
Отладку. Возможно эти переменные еще не инициализированные в этот момент.
 
 Top
DeNCHiK01
Отправлено: 13 Февраля, 2015 - 20:43:59
Post Id


Новичок


Покинул форум
Сообщений всего: 10
Дата рег-ции: Февр. 2015  


Помог: 0 раз(а)




Проверил это сразу. По идее все есть и по логике кода + напрямую функцию sess_write вызываю еще до initialize и все работает.

(Отредактировано автором: 13 Февраля, 2015 - 20:44:46)

 
 Top
Bio man
Отправлено: 13 Февраля, 2015 - 21:58:27
Post Id


Постоянный участник


Покинул форум
Сообщений всего: 2751
Дата рег-ции: Июль 2010  
Откуда: Даугавпилс, Латвия


Помог: 52 раз(а)




global? Глобальные переменные - зло, использовать классы ради классов - тоже зло.
Глобальные объекты не видны, по той причине, что коллбек write вызывается после уничтожения объектов.
Вот, почитай https://bugs.php.net/bug.php?id=50154
Решение - вызывать session_write_close из деструктора.
 
 Top
DeNCHiK01
Отправлено: 16 Февраля, 2015 - 07:26:12
Post Id


Новичок


Покинул форум
Сообщений всего: 10
Дата рег-ции: Февр. 2015  


Помог: 0 раз(а)




Добавил вызов из деструктора, если я, конечно, все правильно сделал, но проблема осталась
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

(Отредактировано автором: 16 Февраля, 2015 - 07:26:43)

 
 Top
exlant
Отправлено: 16 Февраля, 2015 - 21:32:28
Post Id



Посетитель


Покинул форум
Сообщений всего: 425
Дата рег-ции: Февр. 2015  


Помог: 14 раз(а)




Если это при вызове 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 пишет:
использовать классы ради классов - тоже зло.

А учиться же надо как то! Вот и используешь классы ради классов! А понимание приходит спустя время, и с опытом!

(Отредактировано автором: 16 Февраля, 2015 - 21:37:10)

 
 Top
DeNCHiK01
Отправлено: 16 Февраля, 2015 - 23:42:26
Post Id


Новичок


Покинул форум
Сообщений всего: 10
Дата рег-ции: Февр. 2015  


Помог: 0 раз(а)




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%, пожалуйста, поправьте меня, если не прав.
 
 Top
Bio man
Отправлено: 17 Февраля, 2015 - 13:38:53
Post Id


Постоянный участник


Покинул форум
Сообщений всего: 2751
Дата рег-ции: Июль 2010  
Откуда: Даугавпилс, Латвия


Помог: 52 раз(а)




DeNCHiK01, попробуй альтернативную декларацию session_set_save_handler, через интерфейс.
(Добавление)
на php.su устаревшая документация. http://php.net/manual/en/functio...save-handler.php
 
 Top
DeNCHiK01
Отправлено: 17 Февраля, 2015 - 18:31:56
Post Id


Новичок


Покинул форум
Сообщений всего: 10
Дата рег-ции: Февр. 2015  


Помог: 0 раз(а)




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. Стоит обновлять?
 
 Top
Bio man
Отправлено: 17 Февраля, 2015 - 19:51:28
Post Id


Постоянный участник


Покинул форум
Сообщений всего: 2751
Дата рег-ции: Июль 2010  
Откуда: Даугавпилс, Латвия


Помог: 52 раз(а)




DeNCHiK01 пишет:
Стоит обновлять?
читай чейнджлог, если будут изменения без обратной совместимости, и если проект большой, то лучше не стоит.
Если проект небольшой и обнаружатся какие то несовместимости, то их можно быстро поправить.

5.3 версия умерла, она официально не поддерживается, скоро с 5.4 случится тоже самое.
Так что лучше идти в ногу со временем.
 
 Top
DeNCHiK01
Отправлено: 17 Февраля, 2015 - 20:26:30
Post Id


Новичок


Покинул форум
Сообщений всего: 10
Дата рег-ции: Февр. 2015  


Помог: 0 раз(а)




Bio man пишет:
DeNCHiK01 пишет:
Стоит обновлять?
читай чейнджлог, если будут изменения без обратной совместимости, и если проект большой, то лучше не стоит.
Если проект небольшой и обнаружатся какие то несовместимости, то их можно быстро поправить.

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


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


Постоянный участник


Покинул форум
Сообщений всего: 2751
Дата рег-ции: Июль 2010  
Откуда: Даугавпилс, Латвия


Помог: 52 раз(а)




5.5 или 5.6.
5.4 тоже подойдёт
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Если скрипт не работает »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB