Сесія PHP втрачається після перенаправлення

Як вирішити проблему втрати сеансу після перенаправлення в PHP?

Нещодавно я зіткнувся з дуже поширеною проблемою втратити сеанс після перенаправлення. Після пошуку на цьому веб-сайті я все одно не можу знайти рішення (хоча це з'явилося найближчий)

Оновити

Я знайшов відповідь, і думав, що розміщую його тут, щоб допомогти будь-якому, хто зазнає такої ж проблеми.

101
додано Автор trante, джерело
Питання в тому, як вирішити проблему втрати сеансу після перенаправлення в PHP. Я вже зрозумів відповідь, просто розмістивши її тут, щоб інші люди знали. Оскільки моє рішення не в StackOverflow.
додано Автор dayuloli, джерело
Як зазначалося, це стосується FatCow і iPage, а можливо, і інших серверів. І так.
додано Автор dayuloli, джерело
Так, я повинен форматувати питання у формі питання, і тепер це зробити.
додано Автор dayuloli, джерело
@Aris Це неправда, коли у людей є питання про кодування, вони звертаються до StackOverflow за допомогою. Якщо немає відповідей, то вони не можуть отримати необхідну допомогу. Я намагаюся надати таку відповідь.
додано Автор dayuloli, джерело
з моменту його в книзі, мій поганий :)
додано Автор Aris, джерело
Я не помітив це було від вас. Тим не менш, цей сайт відповідає на питання, а не на відповіді на питання, які ви вже знаєте.
додано Автор Aris, джерело
Ви не задаєте питання, ви кажете, що ви будете публікувати відповідь, але ні. не має сенсу...
додано Автор Aris, джерело
Це добре, але це сайт QA. Будь ласка, поставте своє питання на питання.
додано Автор jeremy, джерело
додано Автор David Chen, джерело
У мене така ж проблема з вами, коли я перенаправляю як ім'я домену замість ip-адреси, який вже використовується для запиту HTTP. Можливо, це невідповідність є причиною.
додано Автор Chenhai-胡晨海, джерело
ця помилка виникла лише на вашому сервері або на інших серверах, що не представляють інтересу. також важливе питання Ви можете вибрати свою власну відповідь?
додано Автор amigura, джерело

27 Відповіді

Спочатку виконайте ці звичайні перевірки:

  1. Make sure session_start(); is called before any sessions are being called. So a safe bet would be to put it at the beginning of your page, immediately after the opening <?php declaration before anything else. Also ensure there are no whitespaces/tabs before the opening <?php declaration.
  2. After the header redirect, end the current script using exit(); (Others have also suggested session_write_close(); and session_regenerate_id(true), you can try those as well, but I'd use exit();)
  3. Make sure cookies are enabled in the browser you are using to test it on.
  4. Ensure register_globals is off, you can check this on the php.ini file and also using phpinfo(). Refer to this as to how to turn it off.
  5. Make sure you didn't delete or empty the session
  6. Make sure the key in your $_SESSION superglobal array is not overwritten anywhere
  7. Make sure you redirect to the same domain. So redirecting from a www.yourdomain.com to yourdomain.com doesn't carry the session forward.
  8. Make sure your file extension is .php (it happens!)

Тепер це найпоширеніші помилки, але якщо вони не зробили цього, ця проблема, швидше за все, пов'язана з вашою хостинговою компанією. Якщо все працює на localhost , але не на сервері віддаленого/тестування, це, швидше за все, є винуватцем. Тому перевірте базу знань вашого хостинг-провайдера (також спробуйте їх форуми тощо). Для компаній типу FatCow та iPage вони вимагають вказати session_save_path . Так виглядає так:

session_save_path('"your home directory path"/cgi-bin/tmp');
session_start();

(замініть "шлях вашого домашнього каталогу" у ваш фактичний шлях до домашнього каталогу, який зазвичай знаходиться на панелі керування (або еквівалент), але ви також можете створити файл у файлі test.php у своєму кореневому каталозі та ввести його :

<?php echo $_SERVER['SCRIPT_FILENAME']; ?>

Трохи до "test.php" - ваш шлях до домашнього каталогу. І, звичайно, переконайтеся, що папка насправді існує у вашому кореневому каталозі. (Деякі програми не завантажують порожні папки під час синхронізації)

164
додано
Переключення між http і n https також може стати проблемою stackoverflow.com/questions/441496/…
додано Автор dev.e.loper, джерело
Переконайтеся, що ви перенаправляєте до того самого домену. Таким чином, перенаправлення з www.yourdomain.com до yourdomain.com не містить сеансу вперед.  Вирішено мою проблему
додано Автор Hammad Khan, джерело
session_save_path ('' шлях вашого домашнього каталогу '/ cgi-bin/tmp'); one: p
додано Автор dayuloli, джерело
Чи може це бути проблемою, коли я реєструюсь в підпапках, але в одному домені?
додано Автор arrowman, джерело
Переконайтеся, що ви перенаправляєте до того самого домену. Таким чином, перенаправлення з www.yourdomain.com до yourdomain.com не переносить сеанс. => Це вирішило мою проблему. Велике спасибі.
додано Автор Gaurang, джерело
Отже, який з цих рішень вирішив вашу конкретну проблему?
додано Автор Phil, джерело
Дуже добре написано +1, якщо все не вдається, просто використовуйте файли cookie (випадково створимо рядок і зберігайте його в db і використовуйте його як значення файлу cookie).
додано Автор David Chen, джерело
Крок 2. зробив трюк для мене.
додано Автор Jonast92, джерело
Мої сеанси між сторінками не працювали в субдомені. В даний час працює з: $ some_name = session_name ("some_name"); session_set_cookie_params (0, '/', $ _SERVER ['HTTP_HOST']);
додано Автор Guillaume Renoult, джерело
Зверніть увагу, що з PHP 5.4.0 register_globals було видалено, тому це більше не призведе до проблеми
додано Автор anthonygore, джерело
www-субдомен відсутній у моєму посиланні. бам! спасибі.
додано Автор oMiKeY, джерело
Перевірте журнал помилок веб-сервера теж; у моєму випадку виникла помилка "Не вдалося записати дані сеансу (файли). Будь ласка, перевірте, чи правильний параметр session.save_path". Права доступу були помилковими в каталозі save_path.
додано Автор timbonicus, джерело
Будь-яка причина, чому мої сесії будуть зберігатися десь іншим, ніж в session.save_path?
додано Автор Justin, джерело
Гаразд, дізнався, чому також потрібен session_write_save (). Це тому, що будь-які зміни в вартість $ _SESSION виконуються, коли закінчується скрипт. Переадресація заголовка з виходом (), по суті, перехоплює виконання сценаріїв - тому сеанс потрібно записати на диск/db/redis 'до' переспрямування та виходу! У моєму випадку, переадресації є внутрішніми в домені мого додатка, і я використовую глобальний сценарій включення, так що в моєму додатку все в порядку, щоб включити заяву session_write_close на самому початку мого файлу включення, а не після дуже перенаправлення - менше набравши.
додано Автор Tony Barganski, джерело
Наведений вище пункт 2 про використання виходу() після перенаправлення заголовка виявився неоціненним моментом на одному сайті, у мене ця проблема була. Однак у моєму випадку мені все-таки потрібно додатково запустити session_write_close() у верхній частині мого глобального файлу включати безпосередньо перед моїм оператором session_start (). Увімкнення session.auto_save перериває мої сеанси, тому що мені здається, потрібно мати функцію session_write_save (), яка називається першою - не зовсім вірно чому.
додано Автор Tony Barganski, джерело
Але коли я натискаю посилання "Меню", щоб перевести мене на іншу сторінку, це робить те ж саме, що і домашній і вхідний, змінна невизначена. Я зробив пошук в файлах, і є лише одне місце, яке встановлюється для цієї однієї змінної. Всюди це просто оцінюється. Два дні зараз і немає радості. Немає помилок у PHP, JavaScript або на сервері.
додано Автор IT Serenity, джерело
Я використовую точно такий же код з іншого сайту, який працює на тому ж сервері. Переадресація входу в Home.php .., яка завантажує внутрішню оболонку ..., яка завантажує заголовок, а потім вміст. Я записую значення змінної сесії, яку я відстежую у верхній частині кожного з 4 скриптів PHP одразу після ... if (! Isset ($ _SESSION)) session_start (); Яка перша лінія всіх моїх скриптів PHP. Отже, коли Логін переспрямовує мене додому ... змінна встановлюється належним чином.
додано Автор IT Serenity, джерело
session_save_path ('' ваш шлях до домашнього каталогу '/ cgi-bin/tmp'); session_start (); Це допоможе мені досить Спасибі .............. СПАСИБО ....... СПАСИБІ
додано Автор Ruberandinda Patience, джерело

після заголовка ви повинні використовувати "exit"

header('Location: http://www.example.com/?blabla=blubb');
exit;
19
додано
досконалий! забув цю частину
додано Автор Boris Kamp, джерело
це спрацювало! Дякую
додано Автор Torgia, джерело

Я спробував всі можливі рішення, але ніхто не працював для мене! Звичайно, я використовую загальнодоступну службу хостингу.

Зрештою, я вирішив проблему, використовуючи 'відносний url' всередині заголовка перенаправлення!

header("location: http://example.com/index.php")

скасовано сеансові файли cookie

header("location: index.php")

працював як чарівність!

11
додано
Бра, спасибі, так сильно. Я з цим дуже сильно стикався.
додано Автор Aleksa Ristic, джерело
що працював для мене, дякую вам так багато!
додано Автор Zaphod, джерело

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

У моєму випадку проблема виникла через 404 викликаних через відсутній файл favicon.ico в Chrome і Firefox. Інші навігатори працювали добре.

4
додано
Просто хотів подякувати вам за цю відповідь, змусивши мене зрозуміти, що 404 запити на зображення були перенесені лаком на PHP без будь-яких файлів cookie, і таким чином нові сесії створювалися постійно. Може ніколи не зрозуміло це без тебе.
додано Автор Pascal Zajac, джерело
У мене те ж саме питання, мій favicon.ico перенаправлявся (302 перенаправлення з субдомену на головний домен) і таким чином генерував новий сеанс кожен раз. Дуже дякую!
додано Автор simdrouin, джерело

Це тривалий час зупинило мене (і це повідомлення було чудово знайти!), Але для тих, хто ще не може отримати сеанси між перенаправленнями сторінок на роботу ... Мені довелося перейти до файлу php.ini і перетворити файли cookie на :

session.use_cookies = 1 

Я думав, що сесії працювали без печива ... насправді я знаю, що вони ПОВИЛЬ ... але це фіксувало мою проблему, принаймні, поки я не можу зрозуміти, що може відбуватися у великій картині.

3
додано
Я не знав, що сесії можуть працювати без печива! Дізнайтеся щось нове кожен день! programmerinterview.com/index.php/php -питання/& hellip;
додано Автор dayuloli, джерело
Звичайно, вони можуть працювати без печива залежать від вашої конфігурації. Але ви повинні знати, що ви робите. І майте вагомі підстави для цього. Тому що це менш безпечно. і у випадку, якщо вам доведеться працювати на щось колись без печива. Ви повинні принаймні налаштовувати ini_set ('session.use_strict_mode', '1'); і, як правило, має короткий час сеансу, і після входу користувача використовуйте session_regenerate_id (). Але будьте обережні, якщо хтось публікує посилання на сайт на своєму сервері на форумі, люди, які фактично натискають це посилання, переймуть сеанс. Може бути, перевірка IP також хороша ідея.
додано Автор Michael, джерело

Я потрапив до цього питання на одній конкретній сторінці. Я встановлював значення $ _SESSION на інших сторінках безпосередньо перед перенаправленням, і все працювало нормально. Але ця конкретна сторінка не працювала.

Нарешті я зрозумів, що на цій конкретній сторінці я руйнував сеанс на початку сторінки, але ніколи не запускав його знову. Отже, моя функція знищення змінилася з:

function sessionKill(){

    session_destroy();

}

на:

function sessionKill(){

    session_destroy();
    session_start();

}

І все працювало!

3
додано

У мене була така сама проблема. Незабаром деякі мої змінні сесії не зберегли б на наступній сторінці. Проблема вийшло (у php7.1), ваше розташування заголовка не повинно мати WWW в ньому, наприклад, https://mysite . Гаразд, https: //www.mysite . втратить ці змінні сесій сторінок. Не всі, тільки ця сторінка.

2
додано
Це тому, що www.mysite.com розглядається як абсолютно інший домен, ніж blog.mysite.com або просто mysite.com
додано Автор dayuloli, джерело

У мене була однакова проблема, хоча мій контекст був дещо іншим. У мене була локальна установка для розробки на машині, ім'я хосту якого була windows , а IP-адреса - 192.168.56.2 .

Я маю доступ до системи за допомогою одного з:

Після входу мій PHP-код буде перенаправлено за допомогою:

header('http://windows/');

Якщо попереднє доменне ім'я, яке використовується для доступу до системи, не було windows , дані сеансу будуть втрачені. Я вирішив це, змінивши код на:

header('http://'.$_SERVER['HTTP_HOST'].'/');

Тепер він працює, незалежно від того, яке місцеве доменне ім'я чи IP-адресу вводить користувач.

Я сподіваюсь, що це може бути корисно комусь.

2
додано
session_start();
error_reporting(E_ALL ^ (E_NOTICE | E_WARNING));
if(!isset($_SESSION['name_session'])){
    unset($_SESSION['name_session']);
    session_destroy();
    }   
if(isset($_SESSION['name_session'])){
    $username = $_SESSION['name_session'];
    }
2
додано
Надайте деяке пояснення про те, що ОП зробив неправильно, щоб він міг навчитися насправді, а не просто копіювати код.
додано Автор Granny, джерело

Протягом багатьох днів я боровся з цією проблемою, перевіряючи/намагаючись знайти всі рішення, але проблема полягала в тому, що я знову не викликав session_start (); після перенаправлення. Я тільки припустив, що сесія була "як і раніше жива".

Так що не забувай, що!

1
додано

Інша можлива причина:

Це мій серверний простір. Мій серверний дисковий простір стає повним. Отже, на своєму сервері я видалив декілька файлів і папок і спробував.

Це було працювало !!!

Я зберігаю свій сеанс в AWS Dynamo DB, але він все ще чекає на моєму сервері деякий простір для обробки сеансу. Не впевнений чому !!!

1
додано

Переконайтеся, що новий сеанс створено належним чином, спочатку знищуючи старий сеанс.

    session_start();
   //remove all session variables
    session_unset();
   //destroy the session
    session_destroy();
    session_start();
    $_SESSION['username'] = 'username';

Так, session_start() викликається двічі. Одного разу називають unset і руйнують команди, а другий раз - для початку нового сеансу.

1
додано

У мене була така сама проблема, і знайшов найпростіший спосіб. Я просто перенаправлено до перенаправлення .html з 1 рядком JS

<!DOCTYPE HTML>
<html>
<script type="text/javascript">
<!--
window.location = "admin_index.php";
//–>
</script>
</html>

замість PHP

header_remove();
header('Location: admin_login.php');
die;

Я сподіваюсь, це допоможе.

Любов Грам

1
додано

Якщо ви використовуєте session_set_cookie_params() , ви можете перевірити, чи ви передаєте четвертий параметр $ secure як true . Якщо ви, то вам потрібно отримати доступ до URL за допомогою https.

Параметр $ secure є істинним, це означає, що сеанс доступний лише в захищеному запиті. Це може вплинути на вас локально більше, ніж у сценічних або виробничих середовищах.

Згадуючи це, адже я просто витратив більшість сьогодні намагаючись знайти цю проблему, і саме це вирішило це для мене. Я був просто доданий до цього проекту, і ніхто не згадав, що для цього потрібно https.

Таким чином, ви можете або використовувати https локально, або ви можете встановити параметр $ secure в FALSE , а потім використати http локально. Просто обов'язково встановіть його на справжню, коли ви натискаєте свої зміни.

Залежно від вашого локального сервера, можливо, доведеться відредагувати DocumentRoot у файлі httpd-ssl.conf сервера, щоб ваш локальний URL-адресу було надіслано https.

1
додано

Для мене Firefox зберігає ідентифікатор сеансу (PHPSESSID) у файлі cookie, але Google Chrome використовує параметр GET або POST. Отже, вам потрібно лише переконатися, що повертаючий скрипт (для мене: paypal checkout) здійснює PHPSESSID в параметрі url або POST.

0
додано

У мене теж було таке ж питання, коли перенаправлення не працювало, і спробував усі рішення, які я міг знайти, моя заголовок перенаправлення використовувався у формі.

Я вирішив це, поставив перенаправлення заголовка на іншу сторінку PHP 'signin_action.php' та передавши параметри змінних через я хотів у параметрах url, а потім перепризначити їх у формі 'signin_action.php'.

signin.php

if($stmt->num_rows>0) {
$_SESSION['username'] = $_POST['username'];
echo '<script>window.location.href = "http://'.$root.'/includes/functions/signin_action.php?username='.$_SESSION['username'].'";</script>';
error_reporting(E_ALL);

signin_action.php

<?php
require('../../config/init.php');
$_SESSION['username'] = $_GET['username'];
if ($_SESSION['username']) {

echo '<script>window.location.href = "http://'.$root.'/user/index.php";</script>';
exit();
} else {
echo 'Session not set';
}

?>

Це не прекрасна робота, але вона працювала.

0
додано

Перш за все переконайтеся, що ви телефонуєте session_start() перед використанням змінної $ _ SESSION .

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

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

Найпоширеніші причини, які не згадуються в відповіді @ dyuloli:

  1. Проблема на диску. Переконайтеся, що ваш дисковий простір не заповнений, вам потрібно дещо залишити файли сесій.

  2. Сесійний каталог може бути недоступним для запису. Ви можете перевірити це за допомогою is_writable (session_save_path ())

0
додано

Для мене помилка полягала в тому, що я намагався зберегти об'єкт, що не є унікальним, на сесії, так що виникла помилка при спробі записати сеанс. Але оскільки весь мої коди обробки помилок вже припинили будь-яку операцію, я ніколи не бачив цієї помилки.

Однак я міг знайти це в журналах помилок Apache.

0
додано

Тепер, коли GDPR - це щось, люди, які відвідують це питання, напевно, використовують скрипт cookie. Ну, цей скрипт викликав проблему для мене. Очевидно, PHP використовує файл cookie з назвою PHPSESSID для відстеження сеансу. Якщо цей сценарій видаляє його, ви втратите свої дані.

Я використав цей файл cookie . Він має можливість включити "важливі" файли cookie. Я додав до списку PHPSESSID , сценарій припинив видалення файлу cookie, і все почалося знову працювати.

Ви, мабуть, могли б увімкнути деякі налаштування PHP, щоб уникнути використання PHPSESSID , але якщо скрипт cookie є причиною проблеми, то чому б не виправити це .

0
додано

Якщо ви використовуєте Wordpress, мені довелося додати цей гачок і почати сеанс у init:

function register_my_session() {
    if (!session_id()) {
        session_start();
    }
}
add_action('init', 'register_my_session');
0
додано

Після намагання багато рішень тут на SO та інших блогах ... що для мене було додавання .htaccess до мого сайту root.

RewriteEngine on
RewriteCond %{HTTP_HOST} ^yoursitename.com$
RewriteRule ^.*$ "http\:\/\/www\.yoursitename\.com" [R=301,L]
0
додано

Нічого для мене не спрацювало, але я знайшов, що викликав проблему (і вирішив це):

Перевірте файли cookie та переконайтеся, що файли cookie сеансів PHP на різних піддоменах відсутні (наприклад, для " www.website.com ", а для веб-сайту .com ").

Це було викликано JavaScript, який неправильно використовував субдомен для встановлення файлів cookie та відкриття сторінок в iframes.

0
додано

Просто для запису ... У мене ця проблема, і через кілька годин спробувати все, проблема полягає в тому, що диск був повний, і PHP сесії не могли бути записані в каталог tmp ... так що якщо у вас є ця проблема перевірити, що теж ...

0
додано
Ця відповідь працювала для мене. Ми запускаємо зображення амазонської машини за допомогою nginx. Здається, виникає помилка в тому, що папка сеансів не належить правильному користувачеві (у нашому випадку www ), тому виконується chown-R www.www в папці сеансів виправляє проблему.
додано Автор Joshua, джерело

У мене була така сама проблема, і я відправив орехи в свій код для відповіді. Нарешті, я виявив, що мій хостинг нещодавно оновив версію PHP на своєму сервері і неправильно налаштував параметр session_save_path у файлі php.ini .

Отже, якщо хтось це прочитає, будь-ласка перевірте налаштування php.ini перед іншим.

0
додано

Переконайтеся, що session_write_close не викликається між session_start() і коли ви встановлюєте свій сеанс.

session_start();

[...]

session_write_close();

[...]

$_SESSION['name']='Bob'; //<-- won't save
0
додано

Якщо ви користуєтеся Laravel, і ви зіткнулися з цією проблемою, вам потрібно зберегти дані сеансу перед перенаправленням.

session()->save();
// Redirect the user to the authorization URL.
header('Location: ' . $authorizationUrl);
exit;
0
додано

Я виправив цю проблему після багатьох днів налагодження, і це було все, тому що моя зворотна URL-адреса, що надходить із PayPal Express Checkout, не мала "www". Chrome визнав, що з доменами слід трактувати однакові, але інколи браузери взагалі не працюють. Використовуючи сесії/файли cookie та абсолютні шляхи, не забудьте про "www"!

0
додано
Ukrainian PHP comunity
Ukrainian PHP comunity
885 учасників

dev-ua/php