Az alábbi PHP kódrészlet és output alapján mit rontottam el?
/*Manuális süti beállítás teszteléshez*/
$a = array();
array_push($a,"1");
setcookie("autologin", serialize($a), time() + (365 * 86400), "/");
echo "A: ".serialize($a)."<br>B: "; print_r($a);
/*Teszt vége*/
if(isset($_COOKIE['autologin'])){
$autologin = unserialize($_COOKIE['autologin']);
echo "<br>C: ".$_COOKIE['autologin']."<br>D: "; print_r($autologin);
/*...*/
}
OUTPUT:
A: a:1:{i:0;s:1:"1";}
B: Array ( [0] => 1 )
C: b:0;
D:
Én sem tudom mi a gondod vele de esetleg, hogy a $_COOKIE tömb csak oldalbetöltéskor töltődik fel, nem teszi bele magától a setcookie.
Ha rögtön használni is akarod $_COOKIE tömbből elérve, akkor:
setcookie(....); után:
$_COOKIE['autologin']=serialize($a);
Ugye a sütiket a kliens tárolja. Mikor egy kérés megy a szerver felé, azzal együtt a kliens elküldi a sütiket. Ezeket találod meg a $_COOKIE tömbben. A szerver a válaszban el tud helyezni új sütiket – illetve tudja őket módosítani, törölni – a setcookie()-val, de ezek akkor történnek meg, mikor a válasz megérkezett a klienshez.
A $_COOKIE tehát az kód futásának legelején lesz feltöltve azokkal a sütikkel, amiket a klienstől kapott. A setcookie() majd a HTTP headerben el fogja küldeni az új sütit, de ettől még a $_COOKIE a továbbiakban is azokat a sütiket tartalmazza, amit a kliens küldött. Majd ha a kliens megkapja a PHP által generált sütit, akkor fogja magának lementeni, így a setcookie() által beállított sütik csak a következő oldallekérés során jelennek meg a $_COOKIE tömbben.
Ergo két eset van:
1. Vagy a setcookie() esetén újratöltöd az oldalt. (A legtöbbször ennek nincs sok értelem.)
2. Vagy a setcookie() után vagy előtt a $_COOKIE tömböt is feltöltöd:
setcookie("autologin", serialize($a), time() + (365 * 86400), "/");
$_COOKIE["autologin"] = serialize($a);
(Probléma: a serialize() kétszer fut le feleslegesen, ha módosítasz a kódon két helyen kell.)
Ha átláthatatlanabbul, de biztosabban és gyorsabban akarod csinálni, akkor:
setcookie("autologin", $_COOKIE["autologin"] = serialize($a), time() + (365 * 86400), "/");
Szimpatikusabb megoldás:
$_COOKIE["autologin"] = serialize($a);
setcookie("autologin", $_COOKIE["autologin"], time() + (365 * 86400), "/");
Első futásra:
A: a:1:{i:0;s:1:"1";}
B: Array ( [0] => 1 )
Második futásra:
A: a:1:{i:0;s:1:"1";}
B: Array ( [0] => 1 )
C: a:1:{i:0;s:1:"1";}
D: Array ( [0] => 1 )
~ ~ ~
Itt ugye az az érdekes nálad, hogy az $_COOKIE['autologin'] létezik, és egy "b:0;" értékkel van feltöltve. Ergo ezt valahol valamikor beállítottad. (Mondjuk egy setcookie('autologin',false,…) függvényhívással.)
Három esetet tudok elképzelni, hogy nálad miért az az eredmény, ami…
~ ~ ~ ~ ~ ~ ~
1. A kódban később van egy másik setcookie, ami felülírja az elküldendő süti tartalmát. (Gyanítom nem ez lesz a gond.)
2. A kódban a setcookie előtt már van valamilyen kimenet és a hibakijelzés el van nyomva. Pl.:
<php
error_reporting(E_NONE);
// és/vagy
ini_set("display_errors", "0");
echo "valami"; // Már van kimenet...
setcookie(…); // Ezért nem dolgozza fel a sütiket
Ugye itt azt kell érteni, hogy a szerver HTTP válaszának két része van. (Nem keverendő össze ez a két rész a HTML head és body részével.) Van egy fejléc. Ebben lehet mindenféle fejléchez tartozó információkat átadni a kliensnek, karakterkódolást, content-type-ot, átirányítást, lejárati időt és például a sütiket. Ezeket addig lehet elküldeni, amíg nem érkezik valami a kimenetre, mert onnan már az üzenet törzse következik, az abban elhelyezett setcookie és header függvényhívások már nem kerülnek feldolgozásra, és szépen hibát is ír ki, hacsak nincsenek kikapcsolva a hibajelzések:
Warning: Cannot modify header information - headers already sent by valami.php (output started at valami.php:###) in valami.php on line ###
(Van olyan szerverkonfiguráció, ahol mondjuk a php.ini-ben van alapból kikapcsolva a display_errors, így lehet, hogy nem is kellett semmit tevőlegesen tenned ahhoz, hogy a hibakijelzés ki legyen kapcsolva.)
De sejtésem szerint nem is ez lesz a probléma.
~ ~ ~
3. Szerintem ez lesz a probléma igazi forrása. A sütiknek ugye van elérési útvonala, illetve meg lehet adni elérési útvonalat. Ha elérési útvonal nélkül hívod meg a setcookie()-t, akkor az aktuális útvonal lesz a süti útvonala.
De figyelem! Lehet ugyanazon a néven több süti is, eltérő elérési útvonallal! A kliens ugyan minden sütit visszaküld, de az útvonalra illeszkedés fordított sorrendjében, azaz a $_COOKIE mindig az útvonalra legközelebb illeszkedő sütivel lesz feltöltve.
Pl. van egy ilyen struktúrád:
index.php
login/index.php
Tegyük fel, hogy a login/index.php beállít egy autologin='utvonal_login' sütit, az index.php meg beállít egy autologin='utvonal_root' sütit.
Ekkor két sütid lesz:
autologin=utvonal_login; path='/login'
autologin=utvonal_root; path='/'
A HTTP kérés fejlécében ez lesz:
Cokkie: autologin=utvonal_root; autologin=utvonal_login
Az eredmény:
$_COOKIE = Array('autologin' => 'utvonal_login');
És ez lesz szerintem a gond. Lehet, hogy az ominózus php fájl nem a gyökérmappában található és lehet, hogy egyszer valaha, valamikor beállítottál egy sütit útvonal nélkül: setcookie('autologin','regi');
Ezután hiába állítasz be egy gyökérmappa elérési útra beállított sütit, neked az útvonalra jobban passzoló süti fog átadódni:
setcookie('autologin','valami',time()+365*86400,'/');
Ekkor két sütid lesz:
autologin=regi; path='/login'
autologin=valami; path='/'
És bizony a $_COOKIE makacsul egy 'regi' értéket fog visszaadni. De meg tudod nézni a többit sütit is:
echo $_SERVER['HTTP_COOKIE'];
// Eredmény: autologin=regi; autologin=valami
Megoldás: Töröld a sütiket. Chrome alatt kattints a címsorban az URL előtti 🛈 ikonra, ott a Cookie-k-ra, és ott meg tudod nézni a sütiket, illetve tudod őket törölni.
A másik megoldás (egyszer futtatandó):
setcookie('autologin', 1, time()-1);
setcookie('autologin', 1, time()-1, '/');
(Ez törli mindkét sütit. Akkor megoldás, ha nincs még egyéb – harmadik, negyedik –az útvonalra illeszkedő süti.)
(Amúgy nem csak útvonalra, hanem domainre is lehet ugyanazon a néven több sütid, ott is előfordulhat, hogy van egy valami.hu-ra passzoló sütid, meg egy admin.valami.hu-ra passzoló sütid, amik konfliktusba kerülhetnek.)
Kapcsolódó kérdések:
Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!