Новости Joomla

0 Пользователей и 1 Гость просматривают эту тему.
  • 5 Ответов
  • 3808 Просмотров

Добрый день! Может кто сталкивался с такой трудностью: надо через сессию передать объект (если это важно, то из одного компонента, моего, в стандартный com_user).
У себя в компоненте делаю
Код
        //на всякий случай положил ужо класс в общее место includes, до этого лежал у меня в компоненте
        JLoader::register('Salary', JPATH_SITE.DS.'includes'.DS.'classes'.DS.'salary.php');
        require_once(JPATH_SITE.DS.'includes'.DS.'classes'.DS.'salary.php');                //здесь определение моего класса Salary
        ............................
$form = new Salary();
$form->set('infotype', JRequest::getVar( 'infotype'));
............................
$session =& JFactory::getSession();

//Комментарий 1
        //$session->restart();

$session->set('salary', $form, md5('zp'));

        //Комментарий 2
//$salary =& $session->get('salary', null, md5('zp'));
//$infotype =& $salary->get('infotype');
//echo "You enrer: ".$infotype;

$mainframe->redirect( 'index.php?option=com_user&view=login' );

Так вот если раскоментировать, для проверки, Комментарий 2 и закоментировать редирект в последней строке, то все работает и вижу то что надо(откатываем проверку). Поехали дальше. В components\com_user\views\login\view.html.php вставляю свой код

Код
	require_once(JPATH_SITE.DS.'includes'.DS.'classes'.DS.'salary.php');

$session =& JFactory::getSession();

        //Комментарий 3
//$session->restart();
    //$session->fork();

$salary =& $session->get('salary', null, md5('zp'));
$infotype  =&  $salary->get('infotype');
        ..............................

Так вот в таком вот виде ловлю на последней строке ($infotype  =&  $salary->get('infotype');)
Код
java.lang.RuntimeException: PHP Fatal error:  UserViewLogin::display() [<a href='function.UserViewLogin-display'>function.UserViewLogin-display</a>]: The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition &quot;Salary&quot; of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition  in C:\env\apache-tomcat-6.0.16\webapps\test-joomla\components\com_user\views\login\view.html.php on line 125

php.java.servlet.fastcgi.FastCGIServlet$CGIRunner.parseBody(FastCGIServlet.java:473)
php.java.servlet.fastcgi.FastCGIServlet$CGIRunner.doExecute(FastCGIServlet.java:368)
php.java.servlet.fastcgi.FastCGIServlet$CGIRunner.execute(FastCGIServlet.java:376)
php.java.servlet.CGIServlet.handle(CGIServlet.java:400)
php.java.servlet.PhpCGIServlet.handle(PhpCGIServlet.java:355)
php.java.servlet.CGIServlet.doGet(CGIServlet.java:469)
javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)

есть варианты - если на основании http://www.webdeveloper.com/forum/showthread.php?t=141112&highlight=object+session
если раскоментировать коментарий один, дабы обеспечить старт сессии после определения класса, получаю в той же строке ($infotype  =&  $salary->get('infotype');) - при обращении у объекту

Код
javax.servlet.ServletException: java.lang.RuntimeException: PHP Fatal error:  Call to a member function get() on a non-object in C:\env\apache-tomcat-6.0.16\webapps\test-joomla\components\com_user\views\login\view.html.php on line 125

php.java.servlet.PhpCGIServlet.handle(PhpCGIServlet.java:389)
php.java.servlet.CGIServlet.doGet(CGIServlet.java:469)
javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)

и здесь уже без вариантов :-(
*

smart

  • Администратор
  • 6478
  • 1318 / 15
  • Хочешь сделать хорошо — сделай!
Ну по идее между строчками:

Код: php
$salary =& $session->get('salary', null, md5('zp'));
$infotype  =&  $salary->get('infotype');

необходимо вставить проверку на то, что $salary не пустой, т.е. не null... Потому как гарантий, что эта переменная будет заполнена объектом нет, а значит нужна проверка. Да и в сессию, я лично укладывал бы не сам объект, а его сериализованное представление (использовать функцию serialize перед укладкой, и unserialize после успешной выборки из сессии).

Я лишние проверки здесь не публиковал, да и отключены они сейчас. Так как разумной бизнесреакции на такое поведение (отсутствие/или присутсвие какого-то сырого RAW объекта/ на сессии, в то время как по идее туда положен приличный объект и ожидается что он будет там и дальше, пока его не убрали) нет. Ну разве что пользователю, конечно, нужно показать что-нить более приличное. А мне удобнее чейчас стектрейс видеть :-)
Так вот дальше я не понял, почему это объекта может не быть. И что значит класть на сессию сериализованное представление? Мне казалось, что сериализация сессии в файл или базу - это уже не моя задача (в данном случае). Ну не имя же файла с сериализованным объектом туда класть? Мне кажется что по приведенному моем первом посту линку есть очень близкое объяснение: на сессию можно положить только объекты, классы которых были объявлены до старта сесии. Отсюда и мои эксперименты с рестартом (форком) сесии, после require_once файла с классом. Заметьте - require_once а не include (т.е. PHP файл с классом по идее находит, иначе должен был взорваться здесь). После этого ошибка, кстати, изменяется (см. мой 1й пост).
Попытка заставить работать джумловский лоадер
Код
JLoader::register('Salary', JPATH_SITE.DS.'includes'.DS.'classes'.DS.'salary.php');
тоже ожидаемого результата (__autoload определенная в Loader подхватит мой класс) не дает.

Я конечно могу класть на сессию скалярные переменные (с этим проблем нет) или пользовать что-нить типа JRegistry или $mainframe->setUserState. Но не спортивно это. Нафик такое ООП. Свойств в классе у меня много и перебирать их все несколько раз - мало удовольствия.
*

smart

  • Администратор
  • 6478
  • 1318 / 15
  • Хочешь сделать хорошо — сделай!
Может быть причина вот в этом:

Цитировать
Some types of data can not be serialized thus stored in sessions. It includes resource variables or objects with circular references (i.e. objects which passes a reference to itself to another object).

Не, там все просто. Я его уже для теста упростил до безобразия
Код
<?php
class Salary extends JObject {
public $position;

public function getPosition() {
return $this->position;
}

        public function __sleep() {
                return array('position');
        }

}
?>

а устанавливается значение
   $form = new Salary();
   $form->set('position', JRequest::getVar( 'position'));

т.е. там строка с запросом.

Да, действительно
Цитировать
Мне кажется что по приведенному моем первом посту линку есть очень близкое объяснение: на сессию можно положить только объекты, классы которых были объявлены до старта сесии

пришлось модифицировать JSession - если в метоже конструирования сессии перед ее стартом добавить
Код
JLoader::register('Salary', JPATH_SITE.DS.'includes'.DS.'classes'.DS.'salary.php');
то все начинает чудесным образом работать. Придется сделать какое то более приемлемое решение - создать отдельный, включаемый при старте сесии файл, в котором прописывать свои классы. К сожалению стандартного hook я не нашел.
Чтобы оставить сообщение,
Вам необходимо Войти или Зарегистрироваться
 

Проблема с JRoute а имено с ParseRoute

Автор savenko

Ответов: 8
Просмотров: 3427
Последний ответ 15.09.2014, 14:23:57
от kolio
Проблема с $_Cookie в плагине

Автор turbomaster

Ответов: 1
Просмотров: 1554
Последний ответ 05.12.2011, 14:20:16
от turbomaster
JSession, $_SESSION и captcha

Автор Helios

Ответов: 1
Просмотров: 1969
Последний ответ 17.02.2011, 16:24:43
от Stomp
Плагины для своего компонента - как?

Автор enshtein

Ответов: 5
Просмотров: 1844
Последний ответ 28.01.2010, 15:57:28
от enshtein
Как сделать плагин для своего компонента?

Автор Виталик

Ответов: 3
Просмотров: 2429
Последний ответ 28.12.2009, 11:19:59
от b2z