Подтвердить что ты не робот

Сессия PHP, не записанная после вывода (echo или print_r при внешнем вызове ajax)

У меня есть серьезные проблемы с отладкой этой конкретной проблемы, и я надеюсь, что кто-то подскажет, что я делаю неправильно.

У меня есть пользовательская система CMS, которая использует абзацы в качестве строительных блоков, которые обновляются с использованием вызовов Ajax (prototypejs) и функций, которые анализируют фрагменты HTML в заданном порядке, очищают их и сохраняют эти данные в ассоциативных массивах в переменной сеанса, Вход в систему, сеанс создан, и я могу проверить этот сеанс без проблем на каждой странице, в которой я нуждаюсь. Система работает непосредственно на определенных сайтах, поэтому пользователь может видеть свои обновления в реальном времени и просматривать сайт, как это сделал бы обычный пользователь, но редактирование. Итак, ничего нового здесь нет. Но вот что странно.

Сайт Enduser в режиме редактирования (вход пользователя admin): path "/"

После проверки состояния журнала функция обрабатывает редактируемый контент и сохраняет ассоциативный массив для сеанса, а также запускает некоторые объекты javascript для редактирования каждого абзаца. Фактически данные сохраняются, я могу использовать внешний script, чтобы проверить, есть ли он после этого завершения PHP скрипт. Если я загружаю новую страницу (новый контент), сеанс обновляется новыми данными)

Admin Пользователь изменяет абзац с помощью Inplaceeditor, и этот кусок HTML отправляется через Ajax на php script, который запускает именованный сеанс, считывает текущие данные сеанса, проверяет, должен ли абзац быть изменен, добавлен или удален и переназначен значения для существующих ключей массива в $_SESSION. если я сделаю var_dump() o print_r до $_SESSION после назначения новых данных. После этого script эхо обрабатывает html, а ajax обновляет исходный абзац на вызывающей странице.

Этот script находится в /admin/cms/...etc, что означает не менее 4 каталогов внутри корня сайта.

Когда заканчивается script, я проверяю использование того же дампа сеанса script, чтобы увидеть, действительно ли данные были записаны/зафиксированы, но нет, $_SESSION имеет только исходные данные с вызывающей страницы. Тот же идентификатор, одно и то же имя сеанса, те же session_start(), но данные не записываются. Вся эта операция очень быстрая, поэтому, хотя это может быть проблема скорости, сценарии заканчиваются до того, как session_write_close сможет выполнить свою работу.

Но если я добавлю новый ключ в массив $_SESSION и поместил туда некоторые данные, данные будут обновляться и записываться. Если я ничего не выведу на этом script и просто обрабатываю данные и устанавливаю переменные сеанса, он также обновляется и записывается.

Это похоже на то, что некоторые члены массива $_SESSION блокируются для обновления.

Что я сделал, чтобы отслеживать эту ошибку и что я уверен, что я не ошибаюсь.

  • 1.- register_globals, конечно,
  • 2.- session_name() и session_start() всегда присутствуют и в данном случае заказ. Раньше у меня было несколько session_start() -close на одной странице
    для использования нескольких названных сеансов, но для уточнить проблему, это не дольше поэтому.
  • 3.- Я использую session_write_close() после обработки данных сеанса. Кроме изображения попробовал без, разрешив php решить когда для фиксации данных, но не удачи.
  • 4.- Я использую только файлы cookie для SID.
  • 5.- сессии хранятся в /tmp, я вижу, как данные обновляются.
  • Я также попытался использовать пользовательское сохранение обработчик на БД, но та же проблема,
    "_write" вызывается только при отсутствии выхода в качестве присутствующего.
  • Я искал php.net, stackoverflow, google и т.д. для этой темы. Я никогда не спрашиваю без расследования, это мой первый раз за многие годы... но это просто так нелогично, что это должно быть что-то маленькое, о котором не думал.

Самое странное, что когда я просто обрабатываю данные без вывода $_SESSION, он обновляется в порядке. Но если я изменю этот script, добавив вывод и повторю попытку, вместо того, чтобы просто иметь новое (последнее) значение, я получаю исходное значение назад, тот, который создается вызывающей страницей на первом месте, иногда после игры несколько раз! PHP не может кэшировать значения между скриптами или? У меня нет globlals.

Я действительно невежественный. Эта система работала безупречно на PHP4.3, так как я использую 5.3.3 для двух мотыльков моих пользователей, которые калибруют данные, где смешиваются, поэтому я проверил и да, есть серьезные проблемы. Сегодня я обновился до (5.3.6), и я не могу получить значения этого сеанса.

Script код, вызываемый через Ajax:

<?
session_cache_limiter('nocache'); 
session_name("CMS_ses");
session_start();
include('../htmLawed/htmLawed.php');
include("utils_cms.php");
include("../../../php/utils_array.php");

$value=$_POST['value'];
$editorId=$_POST['editorId'];
$clase=$_POST['clase'];
$editorId=str_replace("pre","",$editorId);
$value=html_entity_decode(stripslashes($value),ENT_QUOTES);
if (strlen(trim($value))==0)
    {
    die();
    }
$value="<div id=\"$editorId\"  class=\"$clase\">$value</div>";

$newXHTML=$value;
$retorno=CMS_nuevoBloque($newXHTML,$editorId);
$_SESSION['data']['CMSeditores']=$retorno[1];   
$_SESSION['data']['CMScont']=$retorno[2];   
session_write_close();

print_r($retorno[0]); //Offending part...without everything works
?>

действительно ничего странного здесь.... код главной страницы еще проще, никаких странных директив php и т.д.

Вот заголовок страницы вызывающего абонента

include 'php/db.php';
$len=$_GET['len'];
$sec=$_GET['sec'];
$cont=$_GET['cont'];
$admfin=$_GET['admfin'];
$fecha=$_GET['fecha'];
$token=$_GET['token'];
$cur=$_GET['cur'];

$PHP_SELF=$_SERVER['PHP_SELF'];
session_cache_limiter('nocache');
session_name("CMS_ses");
session_start();

$passvar='';
unset($adm);
if ((!empty($_SESSION['cms_logged'])) and (!isset($admfin)) )
    {
    $nivelpermisos=$_SESSION['cms_logged_group'];
    $useractual=$_SESSION['cms_logged'];
    $adm=1;

    }
elseif (empty($_SESSION['cms_logged']))
    {
    unset($useractual);
    }
    //.........rest of the code  

ОБНОВЛЕНИЕ: я провёл ночные тесты и обнаружил, что не понимаю. ХЭЛП: Это связано не только с сеансами, но и с запросами Mysql. Тот же код, но вместо того, чтобы писать в массив $_SESSION, я сделал простое обновление таблицы Innodb с помощью session_id. Когда я выхожу на какой-то код, обновление выполняется, (я могу вывести строку запроса и не mysql_error() или уведомление), но при проверке базы данных строка не обновляется. Если вы выберете выход, если script и Query будут совершены. Лишь обычная вещь: сеансы начинаются и выводятся.

Я перезапустил Apache и т.д. (кто знает), но не повезло. Тогда я сделал что-то действительно глупое, потому что это дело на стороне сервера. Я изменил свой браузер на Firefox (используя сафари), и все работает! Хорошо, повторите проверку, вернемся к сафари, ничего не работает. Оба работают бок о бок, одна и та же проблема. PHP - это серверная сторона, как разные браузеры могут обрабатывать код по-разному, может ли браузер говорить об откате Apache, запросить не обрабатывать или вызывать один и тот же script дважды без уведомления (проверена панель разработчика safaris и script вызывается только один раз)? Может ли сафари повторно отправить данные молча, потому что "думает", что ajax не удалось? Я проверил заголовки с помощью инструментов Firebug и Safaris, ничего странного, но всякий раз, когда я делаю вызов Ajax с сафари, страница вызывающего абонента перезагружает данные (Aka conection to server...).

Я действительно ничего не понимаю.

4b9b3361

Ответ 1

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

Возможно, это решит (или поможет вам решить) вашу проблему.

http://php.net/manual/en/function.register-shutdown-function.php

Ответ 2

Благодарим за помощь. Я делал все в правильном порядке, и все еще данные сеанса не записывались. Имена сессий, где это необходимо, потому что иногда мы тестируем много сайтов в одном домене, используя одну и ту же пользовательскую CMS. Итак, наконец, после проведения большого количества тестов и без везения, я обнаружил, что на этом сервере активны регистровые глобальные (мы никогда не используем его, код был написан с учетом этого параметра), но это беспорядок с сеансами!. Переключение этого эффекта сильно изменилось. Больше проблем. Я также создал собственный обработчик сеанса в БД, поэтому я мог отслеживать проблемы более централизованным образом. Conclussion: никогда не используйте регистровые глобалы + названные сеансы, сложные данные в сеансах. Во всяком случае, я дам этой проблеме больше времени и больше тестов. Иногда вызовы Ajax слишком быстры, я должен был выполнить команду сна, поэтому запись данных сеанса была действительно выполнена. Спасибо

Ответ 3

У меня была аналогичная проблема, но у меня было несколько лет назад. IE манипулирует заголовком по-своему и вызывает странные ошибки php, которые вы можете найти в архивах php.net.

@Diego Pino Navarro, см. эту страницу справки и найдите Safari, и он выдает с php.

Я также нашел "Safari" забыл "http-authentication logon-information" .

Ответ 4

Я не уверен, но несколько предложений, которые, я думаю, могут быть полезными.

удалять файлы cookie сеанса перед обновлением страницы для целей тестирования:)

Убедитесь, что вы не назначаете какие-либо массивы с ключом, содержащим символ канала (|). Это предотвратит сериализацию и сохранение данных сеанса.

Выполняет ли session_regenerate_id (true); во многих случаях session_write_close, похоже, не имеет значения с помощью session_regenerate_id. или просто выполните session_start() после session_write_close(), если вы полагаетесь на SID; и в вашем случае я думаю, что это то, что вызывает у вас проблемы, поскольку вы заканчиваете текущий сеанс каждый раз, а не начинаете его для следующей страницы. надеюсь, что у меня будет моя точка зрения. Еще больше Чтобы убедиться, что данные фактически выгружены в браузер, используйте ob_end_flush();

я не мог понять связь между

$_SESSION['data']['CMSeditores']=$retorno[1];   
$_SESSION['data']['CMScont']=$retorno[2];   

и

$nivelpermisos=$_SESSION['cms_logged_group'];
    $useractual=$_SESSION['cms_logged'];

Я думаю, вам нужно вставить еще один код, где часть данных вызывает проблему, а не часть входа в админ.

Надеюсь, это вам поможет.:)

Ответ 5

Есть ли причина, по которой вы дважды устанавливаете имя сеанса? У меня были проблемы в прошлом, где я бы установил сессию без имени, затем другой фрагмент script (не мой) называл сессию. Даже в конце script мне удалось распечатать переменную сеанса, но как только я перешел на новую страницу, моя сессия была забыта. Только после того, как я скопировал имя, включенное во второй script, в мой сеансовый вызов, он был решен.

Проверьте, нет ли других имен сеансов; также, может быть, попробуйте только назвать сеанс один раз, при первом вызове сеанса?

Ответ 6

Вопрос: вы вызываете session_start() в первую очередь... перед ЛЮБОЙ вывод в браузер и перед назначением любых переменных?

Звучит глупо, но попробуйте.

Кроме того, почему вы используете имена сеансов? На самом деле не требуется, если у вас много переменных сеанса с тем же именем, которые используются в разных целях, и если это так, вам нужно сначала исправить это!