В настоящее время я работаю над веб-сайтом с большим количеством столов. Почти во всех таблицах есть фильтры, и поскольку пользователь не хочет терять все свои фильтры при перезагрузке, я сохраняю фильтр в сеансе.
Пока все это работает, я запускаю вызов ajax каждый раз, когда фильтр изменяется, чтобы сохранить новый фильтр в сеансе. Моя проблема в том, когда я пытаюсь очистить фильтры.
Когда пользователь нажимает кнопку очистки или закрывает последнее поле фильтра, ключ сеанса очищается, и он печатает null, но когда я перезагружаю страницу, эти последние фильтры загружаются, и сеанс печатает их, как будто я никогда их не удалял. .
Функция, которую я использую для заполнения / опустошения сеанса:
public function addPersistenceAction(Request $request)
{
$parameters = $request->request->all();
$session = $this->get('session');
$session->start();//I tried removing/adding this line but it didn't change anything
//if the key wasn't send, nothing happends
if (!isset($parameters['storage'])){
return new JsonResponse(0);
}
//if no data was send, it removes the key.
if (!isset($parameters['data'])) {
$session->remove($parameters['storage']);
// I also tried setting an empty array but it didn't work either
//$session->set($parameters['storage'], []);
return new JsonResponse($session->all()); // this prints the correct data
}
//if the data was sent, it is set. This works perfectly
$session->set(
$parameters['storage'],
$parameters['data']
);
return new JsonResponse($session->get($parameters['storage']))
}
Функция всегда возвращает то, что я ожидал, но каждый раз, когда я перезагружаю страницу, у сеанса все еще остается последний фильтр. Я пробовал использовать разные фильтры, и это всегда последний, поэтому он не мог быть закодирован в моем контроллере.
Забавно, я заметил, что если я вручную запускаю функцию, которая получает данные фильтра перед перезагрузкой страницы, она показывает мне правильное значение, и если я перезагружаюсь после этого, фильтр правильно очищается.
Итак, мой вопрос: есть ли причина, по которой кажется, что моя сессия не сохраняется, и есть ли способ программно "заставить" Symfony сохранять данные сессии?
какой-то полезный код:
Функция, которая получает данные сеанса:
/**
* @param Request $request
* @return JsonResponse
*/
public function getSessionDataAction(Request $request){
$parameters = $request->request->all();
$session = $this->get('session');
$session->start();
if (!empty($parameters['storage'])) {
$data = $session->get($parameters['storage'])?:[];
return new JsonResponse($data);
}else{
return new JsonResponse(array('status' => 'failed', 'message' => 'storage is mandatory'));
}
}
Моя функция контроллера:
/**
* @param Request $request
* @return Response
*/
public function indexAction(Request $request)
{
$this->denyAccessUnlessGranted(RoleVoterHelper::SECTION_USER_VIEW);
$session = $request->getSession();
//I checked and the session key I use is not touched in this function
$filterWidgets = $this->get('dmt.filter.manager')->getWidgetData('user_filter');
if (!$this->get('dmt.role_voter')->getExtGranted(RoleVoterHelper::SECTION_USER_VIEW)) {
$filterWidgets['company'] = $this->getDoctrine()->getRepository('BugTrackerModelBundle:Company')->findByAuthorities($this->getUser()->getAuthorities());
}
$authorities = $this->getDoctrine()->getRepository('BugTrackerModelBundle:Authority')->findAll();
return $this->render('DMTBundle:User:index.html.twig', [
'filter_widgets' => $filterWidgets,
'usersColumns' => $session->get('usersColumns'),
'usersSort' => $session->get('usersSort'),
'isSuperAdmin' => $this->isGranted(UserHelper::ROLE_SUPER_ADMIN),
'authorities' => $authorities,
]);
}
JavaScript, вызываемый при открытии страницы:
$.post(dependencies.bridgeGetUrl, {
// something like "project_page_filter", the key for the session.
storage : dependencies.storage
}).success(function(response){
dependencies.filterManager.hook(function(app){
app.scheme = response;
app.readScheme();
});
run(dependencies);
if (typeof dependencies.callback == "function"){
dependencies.callback(dependencies.params);
}
});
javascript, который отправляет любые изменения в сеанс:
App.scheme - всегда текущее значение фильтров.
dependencies.filterManager.setLifecycle(["add", "change-value"], function(app) {
$.post(dependencies.bridgeUrl, {
storage : dependencies.storage,
data : app.scheme
});
}).setLifecycle(["remove-all", "remove"], function(app) {
$.post(dependencies.bridgeUrl, {
storage : dependencies.storage,
data : app.scheme
});
$("#filterSubmit").click();
});
Версия Symfony?
Я использую Symfony 2.8. У меня сейчас нет js, я добавлю его позже, но я знаю, что мой запрос отправлен, потому что они отображаются на вкладке сети инспектора Chrome
Вы также используете $this->get('session') и $request->getSession()? Я бы попытался использовать один и тот же подход с обеих сторон кода
Используете ли вы какую-либо логику "http-кеширования"? У вас установлен FOSHttpCacheBundle или установлен ли заголовок HTTP-кеша с помощью Listener? Может случиться так, что запрос очистки кэшируется браузером, что означает, что он уже был очищен в прошлом, и во второй раз он возвращает кешированный ответ без фактического запроса.
@TarunLalwani Оба метода возвращают один и тот же объект.
Я знаю это, но упоминалось одно решение для использования $request->getSession(), поэтому я хотел, чтобы вы дали ему шанс.
@LioraHaydont Дело не в том, что отправлено если, а в какие и как. ;)
@ Philippe-B: я добавил js, чтобы я знал, нужно ли вам больше кода.
@TarunLalwani Я пробовал везде переходить на $this->get('session'), но это ничего не меняло.
Можно ли минимальный пример воспроизвести? Это может потребовать отладки самого кода Symfony.
@JannesBotis Я не использую никакой логики кеширования http. Фильтры всегда загружаются через js, чтобы убедиться, что он не перезагружает кешированные данные, и поскольку функция get не возвращает то же самое при первой и второй загрузках, я не думаю, что она кешируется
@TarunLalwani, хамм, ну, symfony - это довольно фреймворк для ошибок, и это действительно большой проект, я могу добавить часть представления, которая вызывает js, и она должна запускаться, но вам все равно придется установить и настроить symfony
Если вы упакуете его в одностраничный простой проект, который воспроизводит проблему, я могу помочь
@LioraHaydont, какой браузер вы тестируете? Может случиться так, что кешируются маршруты addPersistent или get. Если это не требует больших усилий, можете ли вы проверить, кэшируются ли ваши запросы, см. stackoverflow.com/questions/13140318/…. Также обратите внимание, что запросы на публикацию также могут иногда кэшироваться: stackoverflow.com/a/14255492/4448410
@JannesBotis Я использую хром для окон. Флажок «Отключить кеширование» также установлен, и запрос занимает достаточно времени, чтобы я мог убедиться, что он не кэширован.
@LioraHaydont Tanks за код. Не могли бы вы добавить консольный журнал отправленных данных?
@LioraHaydont вы можете добавить настройки cookie в конфиг? Что еще более важно, можете ли вы добавить снимок экрана файла cookie в инструменты разработчика Chrome (имя, домен, путь, параметры httpOnly и т. д.)? Хотя понятия не имею, поможет ли это. Попробуйте распечатать идентификатор сеанса для всех запросов, возможно, в заголовке ответа, например header ('test-session-id:'. $ Session-> getId ());
Попробуйте принудительно сохранить сеанс с $session->save() до return в вашей функции addPersistenceAction. В остальном я не верю, что мы сможем легко «угадать», что здесь не так, без воспроизводимого примера. Я вижу, что вы пытаетесь использовать $session->start(), что для меня не имеет смысла, потому что обычно у вас есть session.auto_start = 1 в вашем php.ini, который должен запускать сеанс для вас. Единственное, о чем я могу думать, это проблемы с правами на чтение / запись в пути, где сохраняется сеанс, но это не похоже на проблему здесь.
p.s. Symfony - это фреймворк без ошибок. У них есть тестовое покрытие практически для всего, поэтому я очень сомневаюсь, что это ошибка Symfony, а скорее неправильная конфигурация или неправильное использование.
Я не думаю, что это ошибка Symfony, но я недостаточно работал с сессиями Symfony, чтобы знать, что может заставить сессию вернуться / не сохранить изменения. Я попытался сделать воспроизводимый пример, но как только я удалил все лишнее, пример работал, как ожидалось.
Хорошие новости! Не могли бы вы опубликовать рабочий пример в качестве ответа? Это может помочь людям, столкнувшимся с той же проблемой.
Ну, на самом деле это не решает мою проблему, так как я до сих пор не знаю, что мешает / отменяет сохранение моего сеанса. Я пытаюсь добавить код, пока не найду, какая часть вызывает проблемы
Бьюсь об заклад, это не займет много времени. :) Хотел бы я помочь.




Не могли бы вы добавить javascript, который отправляет вызовы ajax?