Sesi PHP hilang setelah pengalihan

132

Bagaimana cara mengatasi masalah kehilangan sesi setelah pengalihan dalam PHP?

Baru-baru ini, saya mengalami masalah yang sangat umum yaitu kehilangan sesi setelah pengalihan. Dan setelah mencari melalui situs web ini saya masih dapat menemukan solusi (walaupun ini yang paling dekat).

Memperbarui

Saya telah menemukan jawabannya dan saya pikir saya akan mempostingnya di sini untuk membantu siapa saja yang mengalami masalah yang sama.

dayuloli
sumber
1
Pertanyaannya adalah bagaimana menyelesaikan masalah kehilangan satu sesi setelah pengalihan dalam PHP. Saya sudah menemukan jawabannya, cukup posting di sini untuk memberi tahu orang lain. Karena solusi saya tidak ada di StackOverflow.
dayuloli
2
Tidak apa-apa, tapi ini situs QA. Harap ajukan pertanyaan Anda.
jeremy
Saya tidak melihat itu dari Anda. Tetap saja, situs ini untuk pertanyaan, bukan untuk jawaban atas pertanyaan yang sudah Anda ketahui.
Aris
21
@Aris Itu tidak benar, ketika orang memiliki pertanyaan tentang pengkodean, mereka datang ke StackOverflow untuk meminta bantuan. Jika tidak ada jawaban yang tersedia, maka mereka tidak dapat memperoleh bantuan yang mereka butuhkan. Saya mencoba memberikan jawaban itu.
dayuloli

Jawaban:

208

Pertama, lakukan pemeriksaan biasa ini:

  1. Pastikan session_start();dipanggil sebelum sesi apa pun dipanggil. Jadi taruhan yang aman adalah dengan meletakkannya di awal halaman Anda, segera setelah <?phpdeklarasi pembukaan sebelum yang lain. Juga pastikan tidak ada spasi / tab putih sebelum <?phpdeklarasi pembukaan .
  2. Setelah headerpengalihan, akhiri skrip saat ini menggunakan exit();(Orang lain juga menyarankan session_write_close();dan session_regenerate_id(true), Anda dapat mencobanya juga, tapi saya akan menggunakan exit();)
  3. Pastikan cookie diaktifkan di browser yang Anda gunakan untuk mengujinya.
  4. Pastikan register_globalstidak aktif, Anda dapat memeriksa ini pada php.inifile dan juga menggunakan phpinfo(). Lihat ini sebagai cara mematikannya.
  5. Pastikan Anda tidak menghapus atau mengosongkan sesi
  6. Pastikan kunci di $_SESSIONarray superglobal Anda tidak ditimpa di mana pun
  7. Pastikan Anda mengarahkan ulang ke domain yang sama. Jadi pengalihan dari a www.yourdomain.comke yourdomain.comtidak melanjutkan sesi.
  8. Pastikan ekstensi file Anda .php(itu terjadi!)

Sekarang, ini adalah kesalahan paling umum, tetapi jika mereka tidak melakukan trik, masalahnya kemungkinan besar berkaitan dengan perusahaan hosting Anda. Jika semuanya berfungsi localhosttetapi tidak pada server remote / pengujian Anda, maka ini kemungkinan besar penyebabnya. Jadi, periksa basis pengetahuan penyedia hosting Anda (juga coba forum mereka dll). Untuk perusahaan seperti FatCow dan iPage, mereka mengharuskan Anda menentukannya session_save_path. Jadi seperti ini:

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

(ganti "jalur direktori home Anda" dengan jalur direktori home Anda yang sebenarnya. Ini biasanya ada di panel kontrol Anda (atau yang setara), tetapi Anda juga bisa membuat test.phpfile di direktori root dan ketik:

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

Bit sebelum 'test.php' adalah jalur direktori home Anda. Dan tentu saja, pastikan folder itu benar-benar ada dalam direktori root Anda. (Beberapa program tidak mengunggah folder kosong saat menyinkronkan)

dayuloli
sumber
8
+1 yang ditulis dengan sangat baik, jika semuanya gagal, cukup gunakan cookie (menghasilkan string secara acak dan menyimpannya di db dan menggunakannya sebagai nilai cookie Anda).
Dave Chen
2
beralih antara http dan n https mungkin juga menjadi masalah stackoverflow.com/questions/441496/…
dev.e.loper
4
Perhatikan bahwa pada php 5.4.0 register_globals telah dihapus, sehingga tidak akan lagi menyebabkan masalah
anthonygore
2
Periksa log kesalahan server web juga; dalam kasus saya, ada kesalahan "Gagal menulis data sesi (file). Harap verifikasi bahwa pengaturan saat ini session.save_path sudah benar". Izin salah di direktori save_path.
timbonicus
Ada alasan mengapa sesi saya akan disimpan di tempat lain selain di session.save_path?
Justin
26

Anda harus menggunakan "keluar" setelah panggilan header

header('Location: http://www.example.com/?blabla=blubb');
exit;
KraftART Berlin
sumber
Ada bug untuk Gecko (misalnya Waterfox, Firefox, SeaMonkey) di mana jika ada output data (misalnya echo ' ';) atau spasi apa pun, itu akan sepenuhnya mengabaikan header lokasi.
John
18

Saya mencoba semua solusi yang mungkin, tetapi tidak ada yang berhasil! Tentu saja, saya menggunakan layanan hosting bersama.

Pada akhirnya, saya menyelesaikan masalah dengan menggunakan 'url relatif' di dalam header redirect!

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

membatalkan cookie sesi

header("location: index.php")

bekerja seperti pesona!

ali al-juanidi
sumber
7

Saya memiliki masalah yang sama. Saya mengerjakannya selama beberapa jam dan itu membuat saya gila.

Dalam kasus saya masalahnya adalah 404 dipanggil karena favicon.ico yang hilang di Chrome dan Firefox saja. Navigator lain bekerja dengan baik.

Jeremie
sumber
Hanya ingin mengucapkan terima kasih atas jawaban ini, membuat saya menyadari bahwa 404 permintaan untuk gambar sedang diteruskan oleh Varnish ke PHP tanpa cookie dan dengan demikian sesi baru dibuat secara konstan. Mungkin tidak akan pernah berhasil tanpamu.
Pascal Zajac
Saya memiliki masalah yang sama, favicon.ico saya sedang redirect (302 redirect dari subdomain ke domain utama) dan dengan demikian, menghasilkan sesi baru setiap waktu. Terima kasih banyak!
simdrouin
4

Ketika saya menggunakan jalur relatif "dir / file.php" dengan fungsi header () berfungsi untuk saya. Saya pikir sesi tersebut tidak disimpan karena suatu alasan ketika Anda mengarahkan ulang menggunakan url penuh ...

//Does retain the session info for some reason
header("Location: dir");

//Does not retain the session for some reason
header("Location: https://mywebz.com/dir")
pengguna2999967
sumber
3

Ini membuat saya bingung untuk waktu yang lama (dan posting ini sangat bagus untuk ditemukan!) Tetapi bagi siapa pun yang masih tidak bisa mendapatkan sesi antara pengalihan halaman untuk bekerja ... Saya harus masuk ke file php.ini dan menyalakan cookie :

session.use_cookies = 1 

Saya pikir sesi bekerja tanpa cookie ... sebenarnya saya tahu mereka HARUS ... tapi ini memperbaiki masalah saya setidaknya sampai saya bisa mengerti apa yang sedang terjadi di gambar yang lebih besar.

sclarky
sumber
Saya tidak tahu sesi bisa bekerja tanpa cookie! Pelajari sesuatu yang baru setiap hari! programmerinterview.com/index.php/php-questions/…
dayuloli
tentu saja mereka BISA bekerja tanpa cookie tergantung pada konfigurasi Anda. Tetapi Anda harus tahu apa yang Anda lakukan. Dan punya alasan kuat untuk melakukannya. Karena kurang aman. dan jika Anda harus bekerja untuk alasan apa pun tanpa cookie. Anda setidaknya harus mengkonfigurasi ini_set ('session.use_strict_mode', '1'); dan umumnya memiliki waktu sesi singkat dan setelah pengguna masuk, gunakan session_regenerate_id (). Tetapi berhati-hatilah jika beberapa pengguna memposting tautan ke situs di server Anda di forum, orang-orang yang mengklik tautan ini akan mengambil alih sesi. Mungkin memeriksa ip juga merupakan ide bagus.
Michael
3

Saya memiliki masalah yang sama, walaupun konteks saya sedikit berbeda. Saya memiliki pengaturan pengembangan lokal pada mesin yang hostname-nya windowsdan alamat IP-nya 192.168.56.2.

Saya dapat mengakses sistem menggunakan salah satu dari:

Setelah masuk, kode PHP saya akan dialihkan menggunakan:

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

Jika nama domain sebelumnya yang digunakan untuk mengakses sistem tidak windows, data sesi akan hilang. Saya memecahkan ini dengan mengubah kode menjadi:

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

Sekarang berfungsi terlepas dari apa nama domain lokal atau alamat IP yang dimasukkan pengguna.

Semoga ini bermanfaat bagi seseorang.

Stephen K. Karanja
sumber
3

Saya mengalami masalah ini pada satu halaman tertentu. Saya menetapkan nilai $ _SESSION di halaman lain tepat sebelum pengalihan dan semuanya bekerja dengan baik. Tetapi halaman khusus ini tidak berfungsi.

Akhirnya saya menyadari bahwa di halaman khusus ini, saya menghancurkan sesi di awal halaman tetapi tidak pernah memulai lagi. Jadi fungsi hancurkan saya berubah dari:

function sessionKill(){

    session_destroy();

}

untuk:

function sessionKill(){

    session_destroy();
    session_start();

}

Dan semuanya berhasil!

NicB
sumber
3

Saya mengalami masalah yang sama. Tiba-tiba BEBERAPA variabel sesi saya tidak akan bertahan ke halaman berikutnya. Masalahnya ternyata (dalam php7.1) Anda lokasi header tidak harus memiliki WWW di dalamnya, mis https: // mysite . tidak apa-apa, https: //www.mysite . akan kehilangan variabel sesi halaman itu. Tidak semua, hanya halaman itu.

Wynn
sumber
Itu karena www.mysite.comdipandang sebagai domain yang sama sekali berbeda dengan blog.mysite.comatau hanyamysite.com
dayuloli
2

Saya telah berjuang dengan ini selama berhari-hari, memeriksa / mencoba semua solusi, tetapi masalah saya adalah saya tidak menelepon session_start();lagi setelah pengalihan. Saya hanya berasumsi bahwa sesi itu 'masih hidup'.

Jadi jangan lupakan itu!

Jeffrey Roosendaal
sumber
Iya! ini juga masalah saya. Saya pikir memulai sesi PHP seperti menyalakan lampu untuk seluruh rumah. Saya tidak menyadari Anda harus memutar sakelar untuk setiap kamar yang Anda masukkan.
Dale Thompson
1

Saya memiliki masalah yang sama dan menemukan cara termudah. Saya hanya dialihkan ke .html redirect dengan 1 baris JS

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

bukannya PHP

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

Saya harap ini membantu.

Cinta Gram

Gramrock
sumber
1

Jika Anda menggunakan session_set_cookie_params()Anda mungkin ingin memeriksa apakah Anda melewati param keempat $securesebagai true. Jika ya, maka Anda perlu mengakses url menggunakan https.

The $secureparam menjadi sarana yang benar Sidang ini hanya tersedia dalam permintaan aman. Ini mungkin lebih memengaruhi Anda secara lokal daripada di lingkungan panggung atau produksi.

Menyebutnya karena saya baru saja menghabiskan sebagian besar hari ini berusaha menemukan masalah ini, dan inilah yang memecahkannya untuk saya. Saya baru saja ditambahkan ke proyek ini dan tidak ada yang menyebutkan bahwa itu memerlukan https.

Jadi Anda bisa menggunakan https secara lokal, atau Anda dapat mengatur $secureparam FALSEdan kemudian menggunakan http secara lokal. Pastikan untuk mengembalikannya ke true saat Anda mendorong perubahan.

Tergantung pada server lokal Anda, Anda mungkin harus mengedit DocumentRootdi httpd-ssl.confserver sehingga url lokal Anda disajikan https.

Andy Huggins
sumber
1

Alasan lain yang mungkin:

Itu adalah ruang penyimpanan server saya. Ruang disk server saya menjadi penuh. Jadi, saya telah menghapus beberapa file dan folder di server saya dan mencoba.

Itu berhasil !!!

Saya menyimpan sesi saya di AWS Dynamo DB, tetapi masih mengharapkan beberapa ruang di server saya untuk memproses sesi. Tidak yakin kenapa !!!

Jayaprakash
sumber
1

Jika Anda menggunakan Laravel dan Anda mengalami masalah ini, yang Anda butuhkan adalah menyimpan data sesi Anda sebelum mengarahkan.

session()->save();
// Redirect the user to the authorization URL.
header('Location: ' . $authorizationUrl);
exit;
Aubrey Kodar
sumber
0

Saya juga memiliki masalah yang sama dengan pengalihan tidak berfungsi dan mencoba semua solusi yang bisa saya temukan, pengalihan header saya sedang digunakan dalam formulir.

Saya memecahkannya dengan meletakkan redirect header di halaman php yang berbeda 'signin_action.php' dan meneruskan parameter variabel melalui yang saya inginkan dalam parameter url dan kemudian menugaskannya kembali dalam bentuk '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';
}

?>

Ini bukan solusi yang bagus tapi berhasil.

Stacker-flow
sumber
0

Bagi saya kesalahannya adalah bahwa saya mencoba untuk menyimpan objek yang tidak dapat diubah dalam sesi sehingga pengecualian dilemparkan ketika mencoba menulis sesi. Tetapi karena semua kode penanganan kesalahan saya sudah berhenti operasi saya tidak pernah melihat kesalahan.

Saya bisa menemukannya di log kesalahan Apache.

Björn Tantau
sumber
0

Sekadar catatan ... Saya mengalami masalah ini dan setelah beberapa jam mencoba semua masalahnya masalahnya adalah disk sudah penuh, dan sesi php tidak dapat ditulis ke dalam direktori tmp ... jadi jika Anda memiliki masalah ini periksa bahwa terlalu...

iperich
sumber
Jawaban ini berhasil untuk saya. Kami menjalankan Gambar Mesin Amazon dengan nginx. Tampaknya ada kesalahan bahwa folder sesi tidak dimiliki oleh pengguna yang benar (dalam kasus kami www) sehingga melakukan chown -R www.wwwpada folder sesi memperbaiki masalah.
Joshua
0

Bagi saya, Firefox telah menyimpan ID sesi (PHPSESSID) dalam cookie, tetapi Google Chrome telah menggunakan parameter GET atau POST. Jadi, Anda hanya perlu memastikan bahwa skrip yang kembali (untuk saya: checkout paypal) melakukan PHPSESSID di url atau parameter POST.

almisoft
sumber
0

Setelah mencoba banyak solusi di sini di SO dan blog lain ... yang berhasil bagi saya adalah menambahkan .htaccess ke root situs web saya.

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

Jika Anda menggunakan Wordpress, saya harus menambahkan hook ini dan memulai sesi di init:

function register_my_session() {
    if (!session_id()) {
        session_start();
    }
}
add_action('init', 'register_my_session');
Mendongkrak
sumber
0

Tidak ada yang berhasil untuk saya, tetapi saya menemukan apa yang menyebabkan masalah (dan menyelesaikannya):

Periksa cookie browser Anda dan pastikan tidak ada cookie sesi php pada subdomain yang berbeda (seperti satu untuk " www.website.com " dan satu untuk " situs web.com ").

Ini disebabkan oleh javascript yang salah menggunakan subdomain untuk mengatur cookie dan membuka halaman di iframe.

Julius S.
sumber
0

Pertama-tama, pastikan Anda menelepon session_start()sebelum menggunakan $_SESSIONvariabel.

Jika Anda telah menonaktifkan pelaporan kesalahan, coba nyalakan dan lihat hasilnya.

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

Alasan paling umum yang tidak disebutkan dalam jawaban @ dayuloli:

  1. Masalah ruang disk. Pastikan ruang disk Anda tidak penuh, Anda perlu ruang untuk menyimpan file sesi.

  2. Direktori sesi mungkin tidak dapat ditulisi. Anda dapat memeriksanyais_writable(session_save_path())

F0G
sumber
0

Saya mengalami masalah yang sama dan saya pergi mencari kode untuk mencari jawabannya. Akhirnya saya menemukan hosting saya baru-baru ini memperbarui versi PHP di server saya dan tidak benar mengatur session_save_pathparameter pada php.inifile.

Jadi, jika seseorang membaca ini, silakan periksa php.inikonfigurasi sebelum hal lain.

Yova Turnes
sumber
0

Pastikan session_write_closetidak dipanggil antara session_start()dan ketika Anda mengatur sesi Anda.

session_start();

[...]

session_write_close();

[...]

$_SESSION['name']='Bob'; //<-- won't save
Jordan Daigle
sumber
0

Sekarang GDPR adalah suatu hal, orang yang mengunjungi pertanyaan ini mungkin menggunakan skrip cookie. Nah, skrip itu yang menyebabkan masalah bagi saya. Rupanya, PHP menggunakan cookie yang dipanggil PHPSESSIDuntuk melacak sesi. Jika skrip itu menghapusnya, Anda kehilangan data Anda.

Saya menggunakan skrip cookie ini . Ini memiliki opsi untuk mengaktifkan cookie "esensial". saya tambahkanPHPSESSID ke daftar, skrip berhenti menghapus cookie, dan semuanya mulai berfungsi lagi.

Anda mungkin bisa mengaktifkan beberapa pengaturan PHP untuk menghindari penggunaan PHPSESSID, tetapi jika skrip cookie Anda adalah penyebab masalah, mengapa tidak memperbaiki itu .

dodov
sumber
0

Saya memperbaiki masalah ini setelah beberapa hari melakukan debugging dan itu semua karena URL saya yang kembali dari PayPal Express Checkout tidak memiliki 'www'. Chrome mengakui bahwa domain harus diperlakukan sama tetapi browser lain terkadang tidak. Saat menggunakan sesi / cookie dan jalur absolut, jangan lupa 'www'!

miapuffia
sumber
0

Saya memperbaikinya dengan memberikan izin menulis grup ke jalur tempat PHP menyimpan file sesi. Anda dapat menemukan jalur sesi dengan fungsi session_save_path ().

Franzisk
sumber
0

Hari ini saya mengalami masalah ini dalam sebuah proyek dan saya harus mengubah parameter ini menjadi false (atau menghapus baris, secara default dinonaktifkan):

ini_set( 'session.cookie_secure', 1 );

Ini terjadi karena proyek yang sebenarnya berfungsi lebih dari http dan bukan hanya https. Temukan info lebih lanjut di dokumen http://php.net/manual/en/session.security.ini.php

Oscar
sumber
0
ini_set('session.save_path',realpath(dirname($_SERVER['DOCUMENT_ROOT']) . '/../session'));
session_start();

Terlambat untuk menjawab tetapi ini berhasil untuk saya

Vipertecpro
sumber
0

Bagi saya ini adalah kesalahan izin dan ini menyelesaikannya:

chown -R nginx: nginx / var / opt / remi / php73 / lib / php / session

Saya telah menguji beberapa jam di PHP dan tes terakhir yang saya lakukan adalah saya membuat dua file session1.php dan session2.php.

session1.php:

session_start();

$_SESSION["user"] = 123;

header("Location: session2.php");

session2.php:

session_start();

print_r($_SESSION);

dan itu mencetak array kosong.

Pada titik ini, saya pikir itu bisa menjadi masalah server dan pada kenyataannya, itu.

Semoga ini bisa membantu seseorang.

temo
sumber
1
Chown adalah solusi BAD, karena akan diubah kembali ke nilai default pada pembaruan paket. Lihat komentar dalam konfigurasi kumpulan standar (www.conf). Cara yang tepat jika menggunakan direktori lain selain dari apache (mis: / var / lib / php / nginx / session)
Remi Collet
Kamu benar. pembaruan paket adalah alasan masalah saya sejak awal. Tetapi karena itulah yang dilakukan dan saya membutuhkan solusi cepat, ini membantu. Admin SYS saya menyelesaikannya, saya tidak dekat dengan Linux.
temo