Jump to content
  • 0

Передать при помощи сессии ссылку на объект - это нормально?


Быколай
 Share

Question

В общем есть у меня фильтр самописный. Задаю его настройки (какие поля, как фильтровать и т.п.). Затем при каждом дотрагивании до полей фильтра/пагинации он ajax-ом ломиться к простейшему скрипту, который вываливает, используя методы того же класса Filter, готовый ответ.

Встал такой вопрос, надо помимо выбранных пользователем опций (они идут Гетом), настройки фильтра с первой страницы (фронт), передать в ajax-овый скрипт. Чтобы повторно не кастомизировать объект, взял да и прописал:


<?
/*** index.php */
$filter = new Filter();
/** тут сеттеры всякие */
$_SESSION['fltr_obj'] = &$filter;


/** filter.php (вызывается через ajax) */
$filter = $_SESSION['fltr_obj'];

собственно хочу уточнить у людей имеющих более фундаментальные познания в php: стоит ли так делать?

Просто не встречал подобного трюка нигде почему-то. Какие могут быть подводные камни?

А так убиваю зайцев: кастомизация происходит в одном месте, не плодим копии объекта.

Link to comment
Share on other sites

14 answers to this question

Recommended Posts

  • 0


<?
/*** index.php */
$filter = new Filter();
/** тут сеттеры всякие */
$_SESSION['fltr_obj'] = &$filter;

А вы на PHP 4 пишите?

PS: Нет, так делать не стоит. Боюсь представить, что там в хранилище сессии сохранится.

А у вас вообще объект в сессию сохраняется? Нормально?

Link to comment
Share on other sites

  • 0


<?
/*** index.php */
$filter = new Filter();
/** тут сеттеры всякие */
$_SESSION['fltr_obj'] = &$filter;

А вы на PHP 4 пишите?

PS: Нет, так делать не стоит. Боюсь представить, что там в хранилище сессии сохранится.

А у вас вообще объект в сессию сохраняется? Нормально?

php5. В сессии сохраняется ссылка на объект, как и задумывалось. Почему же не стоит, хотелось бы услышать аргументы.

Link to comment
Share on other sites

  • 0

php5. В сессии сохраняется ссылка на объект, как и задумывалось. Почему же не стоит, хотелось бы услышать аргументы.

Тогда ответьте, что в вашем хранилище сессий находится после такого сохранения?

У меня на php 5.4 такой трюк не удался. Интересно, как у вас получается?

Link to comment
Share on other sites

  • 0

php5. В сессии сохраняется ссылка на объект, как и задумывалось. Почему же не стоит, хотелось бы услышать аргументы.

Тогда ответьте, что в вашем хранилище сессий находится после такого сохранения?

У меня на php 5.4 такой трюк не удался. Интересно, как у вас получается?

php 5.3.3

приведу листинг:

Some.class.php


<?
class someClass{
public $id = 0;
function setId($id){
$this->id = $id;
}

function getId(){
return $this->id;
}

}

index.php


<?
require_once 'Some.class.php';
session_start();
$obj = new someClass();

$obj->setId(777);
var_dump($obj->getId());
$_SESSION['obj'] = &$obj;
?>


second.php


<?
require_once 'Some.class.php';
session_start();
$obj = $_SESSION['obj'];

var_dump($obj->getId());

в second.php, после перехода с index.php, получаем то же самое значение => имеем тот же самый объект :yahoo:

Link to comment
Share on other sites

  • 0

Тогда ответьте, что в вашем хранилище сессий находится после такого сохранения?

Спасибо за наводящий вопрос, теперь ситуацию для себя прояснил. С первого раза не понял. А в хранилище у нас:


obj|O:9:"someClass":1:{s:2:"id";i:777;}

сериализованный объект. То есть выходит, что во втором сценарии мы работаем не с жесткой ссылкой, а всё-таки просто копией объекта, т.к. сессия хранит лишь сериализованное представление данных.

В принципе мою задачу такой подход решает: как можно лаконичнее передать копию объекта в другой сценарий.

Почему-то мечтал, что отработает подобно указателю, как в Си, но такого же нет в пыхе :rofl:

Link to comment
Share on other sites

  • 0

В пыхе процесс умирает сразу, как сформирована страница. Это может быть гораздо раньше, чем пользователь увидит эту страницу.

После того, как умер процесс, умирают и все объекты. Т.е. никакой ссылки не может быть.

А теперь представь, что у тебя на сервере сессии будут хранится в файлах. А в твоем объекте будет ни одно св-во, а много. Штук десять. А если у тебя будет более-менее посещаемый сайт, то во первых твое хранилище раздуется до приличных размеров. Во вторых пользователи взорвут диск сервера (утрирую конечно).

Так что я бы не стал привыкать к таким решениям, если в будущем хочешь писать большие проекты.

Либо хотя бы храни все свойства отдельно от объекта. А то не уследишь, отнаследуешь этот класс от какого-то еще, у которого еще десяток-другой свойств или ссылки на другие объекты, и потом будут у тебя в сессиях совершенно левые данные храниться.

А лучше сохранять большие объемы в базе данных. Они для этого и предназначены.

Есть еще куки. Я как-то их применял для хранения данных фильтров. Но там, правда, не было аякса.

На самом деле я слабо представляю, как можно отправляя ajax запрос с клиента выставить значения сессии, но складывается мнение, что у тебя проблемы с архитектурой приложения. Может стоит что-то пересмотреть и потребность сохранять что-то в сессии отпадет.

  • Like 2
Link to comment
Share on other sites

  • 0

Если надо сохранить (условно говоря) 5 свойств объекта, записывай их в БД, куки, файлы (сессионные/нет), так или иначе, порядок объема информации, который окажется на диске один и тот же — пара килобайт. Единственный способ уберечь диск сервера - куки, но т.к. их может изменять пользователь, а следовательно и гипотетически сломать нормальную работу приложения, не стану использовать.

С хранением в БД связан дополнительный код — это надо:

  1. записать, когда надо
  2. прочитать, где надо
  3. не забыть удалить, то что надо, и вовремя

Таким образом вместо двух строк

session_start();
$obj = $_SESSION['obj'];

надо создать таблицу, нагромоздить три SQL запроса, и ещё n-строк кода чтобы работало как следует. Не забываем про индексы, и дисковое пространство сэкономить не удастся.

Про наследование верно подмечено, поэтому прихожу к выводу, что лучше написать метод, вроде getSettings() — и им возвращать только нужные для инициализации свойства. И хранить это в сессии, оттуда пихать например в конструктор нового объекта во втором сценарии. Хотя можно и в тот же GET запихать массив, короче вы меня поколебали))

Архитектура приложения... о да, красивые слова. Но как они мало значат, когда дедлайн ставиться одновременно с задачей, а манагер имеет отношение к разработке ПО чуть менее чем никакого, и начальство интересует только инструмент для продаж, а не его архитектура :devil:

Link to comment
Share on other sites

  • 0

Ну, к примеру, тот же Yii генерирует за тебя код и формирует запросы. Тебе надо только немного поднастроить модель и все ))) Получается быстро написанный код (шаблоны генератора можешь сам менять), в целом не плохая архитектура. Модель можешь использовать точно так же ))) Написать ей метод getSettings() и вперед!

Честно говоря все равно не понимаю, как ajax может требовать писать что-то в сессии или в бд.

Вот есть у тебя сформированная страница. Ты на ней выставляешь параметр и жмешь "искать". Когда он записывает что-то в сессию? Ведь скрипту, который обрабатывает запрос все параметры надо передавать через GET/POST. Запрос инициализируется браузером. Следовательно, мне не понятно, при каких обстоятельствах основная страница передает данные аяксовой странице через сессию.

Link to comment
Share on other sites

  • 0

Честно говоря все равно не понимаю, как ajax может требовать писать что-то в сессии или в бд.

Нет, ты не верно понял. Изначально был такой алгоритм:

1. index.php - инициализируется фильтр, настраивается. В сессию записывается его копия.

2. В filter.php (который на ajax отвечает), из сессии забираются параметры объекта фильтра (настройки — где и как ищем), а пользовательские контролы приходят в GET.

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

MVC это хорошо. В перспективе конечно хочется переписать весь сайт на каком-нибудь фреймворке, т.к. сейчас он на устаревшем и искалеченном костылями предшественником и мной битриксе, и цеплять туда ещё и фреймворк, уже слишком. Была уже мысль разделить существующий Filter.class.php на три части, но городить огород тут... Реализация достаточно компактная и универсальная получилась.

А проблемы, увы, приходится решать по мере поступления и буйства фантазии начальства, а не в соответствии со сферической архитектурой в вакууме, о которой пока можно только мечтать :)

Edited by Быколай
Link to comment
Share on other sites

  • 0

>что лучше написать метод, вроде getSettings() — и им возвращать только нужные для инициализации свойства

Посмотрите магические методы __sleep() and __wakeup()

MiksIr, интересно. Только не понятно как массив из __sleep вернуть?

И ещё минус такой, что придётся приватные свойства "рассекретить", чтобы использовать их.

Link to comment
Share on other sites

  • 0

  1. Обычно выводится форма фильтра со всеми инпутами, в которых находятся нужные дефолтовые значения. Пользователь же их может изменять.
  2. Далее после какого-то события отправляешь эту форму на твой аяксовый скрипт. Например, этим http://www.malsup.com/jquery/form/
  3. В аяксовом скрипте просто инициализируешь свой фильтр, передавая ему параметры, которые пришли в POST или GET.
  4. На основе фильтра формируешь SQL запрос и выводишь данные.
  5. Профит ;)

ЗЫЖ Я бы не стал все на столько усложнять c сессиями, сериализацией и т.д. Чем проще, тем лучше.

Link to comment
Share on other sites

  • 0

  1. Обычно выводится форма фильтра со всеми инпутами, в которых находятся нужные дефолтовые значения. Пользователь же их может изменять.
  2. Далее после какого-то события отправляешь эту форму на твой аяксовый скрипт. Например, этим http://www.malsup.com/jquery/form/
  3. В аяксовом скрипте просто инициализируешь свой фильтр, передавая ему параметры, которые пришли в POST или GET.
  4. На основе фильтра формируешь SQL запрос и выводишь данные.
  5. Профит ;)

ЗЫЖ Я бы не стал все на столько усложнять c сессиями, сериализацией и т.д. Чем проще, тем лучше.

да примерно так и происходит

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. See more about our Guidelines and Privacy Policy