Outo ongelma sessionin kanssa. Kotikoneella, jossa on PHP 5, toimii hyvin. Verkossa, jossa on PHP 4, ei toimi.
Warning: session_start(): Cannot send session cookie - headers already sent by (output started at ...................... /index.php:1) in .................... on line 3 Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at ..................../index.php:1) in ............................. on line 3
Ennen session_start komentoa ei tulosteta mitään.
Olen tarkistanut myös tiedoston prepend.php, siinäkään ei tulosteta mitään.
Ovatko tiedoston ensimmäiset merkit varmasti <?php
, eikä niitä ennen ole vaikkapa rivinvaihtoa? Harvemmin noita ilmoituksia tulee turhaan.
Antti Laaksonen kirjoitti:
Ovatko tiedoston ensimmäiset merkit varmasti
<?php
, eikä niitä ennen ole vaikkapa rivinvaihtoa? Harvemmin noita ilmoituksia tulee turhaan.
Oli ne tietty eri rivillä. Mutta niinhän se on ennenkin ollut ja on toiminut.
Laitoin nyt kaikki eka-riville.
<?php ob_start(); session_start(); ?>
Vielä on jokin ongelma. Ei aseta istuntoa, kun sen aika on. Kotikoneella toimii sekin.
Olen nyt eri koneella, tästä on hiukan hankala poimia koodia.
function istunto($arvo, $arvo2, $arvo3){ session_register("taulu"); $array = array("yksi"=>$arvo,"kaksi"=>$arvo2,"kolme"=>$arvo3); return($_SESSION["taulu"][] = $array); } istunto($_POST["eunimi"],$_POST["sukunimi"],$_POST["paikkakunta"]);
Tässäpä olisi koodia (muuttujanimet hiukan muutettu), joka toimii asettaen istunnon omalla koneella muttei PHP 4:ssä verkkosivulla. Kaikki syötetyt POST-tiedot toimii oikein molemmissa tapauksissa.
ja olet siis täysin varma, ettei missään php-skriptissä ole tulostettuna mitään (edes tyhjää riviä) ennen session aloitusta (ts. <?php tägiä)
Lebe80 kirjoitti:
ja olet siis täysin varma, ettei missään php-skriptissä ole tulostettuna mitään (edes tyhjää riviä) ennen session aloitusta (ts. <?php tägiä)
Ei sellaista tyhjää merkkiä tai riviä ainakaan löydy mistään.
Tuokin, mikä oli, oli php-tagin sisällä oleva rivinvaihto ja noiden muuttaminen samalle riville poisti kaikki virheilmoitukset.
Tutkin sessionin sisällön näin:
if($_SESSION["taulu"][0] !=''){ // tulostetaan... }
Tuota tyhjää merkkiä olen etsinyt myös siten, että kotikoneella olen tiedoston alkuun tulostanut prepend.php-tiedoston sisällön, mutta silti toimii oikein kotikoneella. Joten tyhjää merkkiä ei näyttäisi olevan siinäkään.
Firefox selain ja asenna siihen tämä plugin: http://livehttpheaders.mozdev.org/
Sen jälkeen firefoxin valikko Näytä->LiveHTTPHeaders sekä sen jälkeen katso tuota sivua joka tuottaa virheilmoituksen.
Sen jälkeen clip-clip ja ota sieltä headeri infot vaikka tänne keskusteluun ja tutkitaan.
Erittäin näppärä työkalu selvitellä juuri noita headers ongelmia.
-W-
Sulla on kotikoneella output_buffering säädetty päälle php.inistä ja palvelimella ei jotenka se tulee päälle vasta ob_start() function suorittamisen jälkeen. Siksi tiedoston alussa oleva ns näkymätön merkki aiheuttaa ongelman. Välilyöntiä ei helposti huomaa. Sekä muutaman kerran olen saanut Crimson editor bugaamaan ja se on tallentanut tiedoston alkuun jotain ihmeellistä ja eikä näyttänyt sitä.
Kiitos. Pitää tarkastella jokin hetki. Minulla ei tällä koneella ole kuin IE, tilan puutteen vuoksi. Pitää tutkia, voisiko väliaikaisesti asentaa tuon Firefoxin.
Laitoin tästä jo kyselyn ylläpidolle. Sieltä ei nyt ole vastausta vielä tulossa, kun asiakaspalvelu on avoinna vain klo. 16 saakka.
Se jotain ihmeellistä on voinut olla Byte-Order Mark. Miksi istunto-funktio palauttaa jotain (mitä ikinä tuo nyt sitten palauttaakaan)? Voisit kutsua session_starttia istuntofunkkarissa tuon session_registerin sijaan.
Opiskelija: php.inissä tuo on tällä tavoin:
output_buffering = 4096
Löysin nyt yhden "erikoisuuden" lisää:
// Metodi: Array tulostuu sessionista heti lisäyksen jälkeen. function istunto($arvo, $arvo2, $arvo3){ session_register("taulu"); $array = array("yksi"=>$arvo,"kaksi"=>$arvo2,"kolme"=>$arvo3); $_SESSION["taulu"][] = $array; print_r($_SESSION["taulu"]); return($_SESSION["taulu"]); } // klikataan seuraavaksi alasivulle katsomaan, tulostuuko session: // Array ei enää tulostu print_r($_SESSION["taulu"]); // Ei tulostu edes tietoa tyhjästä arraysta ( Array() );
Viitaisi vähän semmoiseen, että session "kuolee" heti, kun sivu päivitetään.
Toisaalta, jos päivitetään jatkuvasti lomakkeen lähetys, se lisää session-arrayhin samaa tavaraa eikä poista entistä.
Kannattaa tarkistaa, että session käynnistyy oikein. PHP.ini:ssähän tuo määritellään, yleensä kannattaa .htaccess tiedostolla määritellä, että session ei käynnisty automaattisesti. Tämän jälkeen sitä on koodissa helpompi kontroloida ja varsinkin kun koodia siirretään alustalta toiselle.
Ongelma voisi viitata siihen, että toinen palvelin aloittaa sessiot ja toinen ei. Väännä kaikki virhetulostuksen päälle PHP:ssä ja lue sieltä, että mikä mättää.
Suositus: käytä bootstrap tiedostoa (eli kaikki liikenne ohjautuu index.php tiedostoon .htaccess+rewrite metodilla). Helpompi hallita noita headers ongelmia.
-W-
Pekka Mansikka kirjoitti:
Opiskelija: php.inissä tuo on tällä tavoin:
output_buffering = 4096
Kommentoippas tuo ja zlib jutut, niin saat kotikoneellasikin ilmoituksen siitä ylimääräsestä merkistä. Nuo kun laittaa bufferoinnin päälle ennenkuin PHP-tulkki alkaa tulkkaamaan index.php tiedostoasi.
Ja onkos tuo PHP 4 riittävän uusi, jotta osaa super globaalit?
tsuriga kirjoitti:
Se jotain ihmeellistä on voinut olla Byte-Order Mark.
Ehkäpä, kerran selain näytti sen laatikkona.
tsuriga kirjoitti:
Miksi istunto-funktio palauttaa jotain
Periaatteessahan functioiden pitäisi aina palauttaa jotain.
Olen kommentoinut tuon bufferingin, mutta ei vaikuta kotikoneella mitenkään.
Tämän verran olen muuttanut tuota tulostusjuttua:
$cnt = count($_SESSION["taulu"]); if($cnt >0){ // tulostetaan... }
Tämä siksi, että kävijä on voinut poistaa asian, joka on avaimessa 0.
Laitoin print error_reporting(E_ALL); etusivulle, mutta se listasi vain noticeja, joista muutaman muutin.
Mikä on Byte-Order Mark?
Ps:
lainaus:
Suositus: käytä bootstrap tiedostoa (eli kaikki liikenne ohjautuu index.php tiedostoon .htaccess+rewrite metodilla). Helpompi hallita noita headers ongelmia.
Mitä htaccess-tiedostoon tulisi kirjoittaa?
RewriteEngine on
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php
Lyhyesti tarkoitettuna kaikki muut kohdistuvat pyynnöt ohjataat index.php tiedostolle, paitse ne pyynnöt joiden tiedostopääte on listassa.
Huom! Esim. PDF tiedostot on tuosta rajatta pois sen takia, että ne muodostetaan monesti "lennossa" tai ne tuodaan jostain ei-julkisesta taustapalvelusta käyttäjän ulottuville.
Sitten jos on alihakemistoja joissa on esim. kuvia, niin silloin tietysti pitää alihakemistoihin sijoittaa .htaccess tiedosto samalla tyylillä. Tosin, itse suosittelen käyttämään eri palvelinnimeä/osoitetta staattiselle sisällölle ja scriptipalvelimelle. Saa hieman lisää nopeutta nimittäin kun konfataan palvelimet eri tavalla...
-W-
Tulisiko php-tiedostossa olla lisäksi jokin tietty juttu?
Tällä hetkellä siinä on E_ALL tulostus, ja se tulostaa aina 2039, ei muuta.
Pekka Mansikka kirjoitti:
Mikä on Byte-Order Mark?
Näkymätön merkki tiedoston alussa, joka kertoo, miten loput tiedostosta pitäis tulkita.
http://en.wikipedia.org/wiki/Byte_Order_Mark
Opiskelija kirjoitti:
tsuriga kirjoitti:
Miksi istunto-funktio palauttaa jotain
Periaatteessahan functioiden pitäisi aina palauttaa jotain.
PHP:ssä return on valinnainen, funktiot voivat olla myös void-funktioita. Lisäksi tekisin mieluummin kahdessa osassa tuon sijoituksen ja palautuksen niin tuosta näkisi selvästi, mitä se palauttaa.
Pekka Mansikka kirjoitti:
Tulisiko php-tiedostossa olla lisäksi jokin tietty juttu?
Tällä hetkellä siinä on E_ALL tulostus, ja se tulostaa aina 2039, ei muuta.
Jos tarkoitat bootstrap tiedostoa, niin ei. Vaatimuksena Apache jossa rewrite mokkula päällä ja .htaccess tiedostoille riittävästi oikeuksia Apachen konfissa.
--W--
Empä ole saanut tähän mitään selkeyttä.
Kokeilin tuota Firefox-juttuakin. Sain sen asennettua ja jäi vielä hiukan vapaatakin tilaa.
En tiedä, täytyykö siinä jotakin säätää. Ei antanut mitään erityistä ilmoitusta tuo LiveHTTP Headers. Tältä Ohjelmointiputkan sivulta se antaa ihan samat ilmoitukset.
Mutta sen olen testannut, että tuo session-juttu kärsii olla ilman ob_start-funktiota (sitä tarvitaan vasta myöhemmin header-funktiolle). Eli ilmeisesti tyhjää ei ole....
Kokeilepa ihan tekemällä yksi uusi php-skripti, jolla testailet ob_starttia ja sessioita, ja joilla tulostat session sisältöjä ja joilla ilmoitat oliko sessioon asetettu mitään ja mitä siellä on asetuksen jälkeen yms. eli ihan perusdebug-sivu. Tämän jälkeen kun olet saanut tämän toimimaan, alat katsomaan missä se virhe saattaisi nykyisessä "järjestelmässäsi" olla.
<?php session_start(); if($_GET["sivu"] == "testi"){ session_register("testi"); $_SESSION["testi"][0] = array("a"=>"a","b"=>"b","c"=>"c"); echo "SIVU 1: SESSION ASENNETTU<br>"; } if($_GET["sivu"] == "testi2"){ echo "SIVU 2: TESTAUKSEN TULOS:<br>"; print_r($_SESSION["testi"]); } ?> <a href="testi.php?sivu=testi">Session</a> <a href="testi.php?sivu=testi2">Testaa</a>
Sama on pulma tässä testissäkin. Testi on nähtävissä seuraavassa osoitteessa:
http://www.pm-netti.com/koe/testi.php
Toisaalta varsinaisessa ohjelmassani session asetetaan etusivulla, mutta vasta POST-silmukassa if(isset($_POST["listaan"])). Vastannee tässä tapauksessa toiminnaltaan aika lailla tuota $_GET["sivu"] juttua tuossa testi.php:ssa.
Testasin myös, että mikäli session asetetaan etusivulla eikä alasivulla, silloin tuo session näkyy tuossa alasivulla.
Eli näin:
<?php session_start(); session_register("testi"); $_SESSION["testi"][0] = array("a"=>"a","b"=>"b","c"=>"c"); echo "SIVU 1: SESSION ASENNETTU<br>"; if($_GET["sivu"] == "testi2"){ echo "SIVU 2: TESTAUKSEN TULOS:<br>"; print_r($_SESSION["testi"]); } ?> <a href="testi2.php?sivu=testi2">Testaa</a>
Tämä on nähtävissä taas tässä:
http://www.pm-netti.com/koe/testi2.php
Pekka Mansikka kirjoitti:
Empä ole saanut tähän mitään selkeyttä.
Kokeilin tuota Firefox-juttuakin. Sain sen asennettua ja jäi vielä hiukan vapaatakin tilaa.
En tiedä, täytyykö siinä jotakin säätää. Ei antanut mitään erityistä ilmoitusta tuo LiveHTTP Headers. Tältä Ohjelmointiputkan sivulta se antaa ihan samat ilmoitukset.
Mutta sen olen testannut, että tuo session-juttu kärsii olla ilman ob_start-funktiota (sitä tarvitaan vasta myöhemmin header-funktiolle). Eli ilmeisesti tyhjää ei ole....
LiteHTTPHeaders ei anna ilmoitusta, mutta se kertoo, että mitä headereita palvelin lähettää. Niitä vertaat sitten siihen mitä sen PITÄISI lähettää. Jos palvelin lähettää yhdenkin merkin ennen itse määrittelemisiäsi headereita, niin silloin lähetetään oletusheaderit.
Ja mitä tulee tuohon järjestykseen ob_start kanssa, niin:
<?php ob_start(); session_start(); $_SESSION['testi'][0] = array('a'=>'a','b'=>'b','c'=>'c'); echo 'SIVU 1: SESSION ASENNETTU<br>'; if($_GET['sivu'] == 'testi2' ): echo 'SIVU 2: TESTAUKSEN TULOS:<br>'; endif; if ( isset($_SESSION['testi']) ): print_r($_SESSION['testi']); else: echo 'ei testiä'; endif; ob_end_flush(); ?>
Muista myös, että session_register ei toimi ympäristöissä joissa register_globals on disabloitu!!! Tämä on muuten ero PHP4 ja PHP5 ympäristöissä muistaakseni: PHP5:ssä register_globals on oletuksena disabled tilassa. Monesti se myös palveluntarjoajien osalta väännettään disabled tilaan eli kannattaa tarkistaa. Session_register funktiota ei myöskään kannata käyttää jos käyttää $_SESSION.
Tosin en käsitä miksi käytetään $_SESSION dataa jos dataa ei tarvita yhä uudelleen ja uudelleen kun sama käyttäjä palaa. Session lienee yksi eniten turhaan ja väärin käytetyistä asioista. Tosin tämän scriptin tarkoitusperiä en tiedä, mutta kannattaa aina miettiä, että jos samaa dataa alustetaan joka kerta uudelleen sessioon, niin onko siinä järkeä? Saman saa aikaiseksi esim. $GLOBALS kauttakin. Ja kannattaa ottaa huomioon, että sessiot ei toimi klustereissa vaan siihen tarvitaan isoa käsittelyoperaatiota...
-W-
En käsitä miksi roikutat tuota session_registeriä mukana kun käytät kumminkin session_starttia manuaalisesti. Käytät sitä myös manuaalin ohjeiden vastaisesti ja se on kaiken lisäksi deprekoitu.
ja luetaan niitä ohjeita:
// Use of session_register() is deprecated $barney = "A big purple dinosaur."; session_register("barney");
Muuttuja $barney ja session_register("barney"). Löydä yhteys.
Huomaa myös "session_register() is deprecated"
Olen nyt muuttanut tuota testi.php tiediostoa seuraavasti.
<?php ob_start(); session_start(); if($_GET["sivu"] == "testi"){ $testia = "Taulu"; session_register("testia"); $_SESSION[$testia][0] = array("a"=>"a","b"=>"b","c"=>"c"); echo "SIVU 1: SESSION ASENNETTU<br>"; } if($_GET["sivu"] == "testi2"): echo "SIVU 2: TESTAUKSEN TULOS:<br>"; endif; if ( isset($_SESSION[$testia]) ): print_r($_SESSION[$testia]); else: echo 'ei testiä'; endif; ob_end_flush(); ?> <a href="testi.php?sivu=testi">Session</a> <a href="testi.php?sivu=testi2">Testaa</a>
Edelleen session häipyy, kun klikkaa linkkiä.
Ota session_register pois
Wizard kirjoitti:
Ota session_register pois
Otettu on.
Edit: Muokkaus klo. 14:56
Live HTTP headers tulosti pitkällä viivellä tällaista kohdassa "HTTP Headers":
http://sb.google.com/safebrowsing/update?client=navclient-auto-ffox&appver=2.0.0.9&version=goog-white-domain:1:23,goog-white-url:1:371,goog-black-url:1:16154,goog-black-enchash:1:38107 GET /safebrowsing/update?client=navclient-auto-ffox&appver=2.0.0.9&version=goog-white-domain:1:23,goog-white-url:1:371,goog-black-url:1:16154,goog-black-enchash:1:38107 HTTP/1.1 Host: sb.google.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fi; rv:1.8.1.9) Gecko/20071025 Firefox/2.0.0.9 Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 Accept-Language: fi Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive Cookie: SID=DQAAAH8AAADrfhnrnyqXpZT8O9qSDISiaomf29eBHvWShyfrIfshvhB8fAW8jvU9-TuP7EJKLX0fDBqfPdLS-Buq-28cEQny4nptrit3AkHocTzWegj_hAmZ-cbBjkehSsUawD5iqQArRIurAd3kBLLokYQB5FlhVQwhGJWQbtZt5XbTkEXDEQ; NID=5=mi4hVfvFTGgw7TATGn96oc3gxnOroG-ElMSntwETmBk4l2j74CREqBlQZLIxfAUegBa9bsH4_p7NihlDeK7ScyDyTVSAJnq7jz4URIWOHBDmUxo1EmYf8ZFhWVIcYbrW; rememberme=true; PREF=ID=c542ae15cc9745de:TB=2:TM=1188155868:LM=1190466206:DV=AA:GM=1:IG=3:S=89ZJibJk405J60Cs HTTP/1.x 200 OK Content-Type: text/html; charset=UTF-8 Cache-Control: public,max-age=600 Server: TrustRank Frontend Transfer-Encoding: chunked Content-Encoding: gzip Date: Thu, 15 Nov 2007 12:49:02 GMT ----------------------------------------------------------
Eli tuo olisi klo 14:49 suomen aikaa oleva tilanne.
Huomasin tuossa juuri, että osoiterivillä session on tähän tyyliin:
http://www.pm-netti.com/xxxx/xxxx/index.php?amp;SID=044903a2d88631e76334a71299645b0e
Haittaako tuo, että siinä on tuo amp; ?
Tässä palvelimen session_name asetus.
[session.name] => Array ( [global_value] => PHPSESSID [local_value] => amp;SID [access] => 7 )
Edit: Kotikoneella noissa molemmissa lukee PHPSESSID
Edit 2 klo 14.47: Sain tämän muutettua htaccess-tiedostosta ja alkoi toimimaan.
Aihe on jo aika vanha, joten et voi enää vastata siihen.