ugrás a tartalomhoz

Warning: session_start()

Petrusz · 2009. Szep. 29. (K), 00.09
Sziasztok!

Localhoston minden problem nélkül lefut a session, de a freeweben már nem. Mit tudok tenni..a program miatt jó lenne sessiont használnom

Warning: session_start(): Cannot send session cookie - headers already sent by (output started at /disk/raid4/w/e/weberp/eclient/index.php:6) in /disk/raid4/w/e/weberp/eclient/index.php on line 27

Köszönöm!

Péter
 
1

keress egy picit

gex · 2009. Szep. 29. (K), 00.21
keress egy picit, biztos találsz valami hasznosat...
2

OK igazad van!

Petrusz · 2009. Szep. 29. (K), 08.49
Van is egy location utasítás a session előtt, tehát ha ezt kipufferelem a session előtt akkor jó lesz? (ob_end_flush)
3

majdnem

a.d.a.m · 2009. Szep. 29. (K), 13.41
ob_start() a megfelelő parancs (az ob_end_flush:
A kimeneti puffer ürítése (kiküldése), és a kimeneti pufferelés lekapcsolása
ezt a session után add ki.)
4

vagy

csman007 · 2009. Szep. 29. (K), 15.39
vagy csak igy Írd:
  1. @session_start();  
7

Nope

janoszen · 2009. Szep. 29. (K), 19.10
Ez tök jó, csak pont célodat nem fogod elérni vele, mert nem fog működni a session. A kukac (avagy kussoltató operátor) használata egyébként is barbár szokás, mert amit az elrejt, az mind-mind programozási gyengeségre vall. Avagy: a Notice is hiba, a Warning pedig végképp az. Tessék lekezelni őket!
5

Köszönöm a hozzászólásokat

Petrusz · 2009. Szep. 29. (K), 16.27
Tehát a lenti code-ba a session start és a header:location közé adjam ki az ob_start()-ot pl 37. sor?
  1. <html>  
  2. <head>  
  3. <link rel="stylesheet" type="text/css" href="eclient.css" />  
  4. </head>  
  5.   
  6. <?php  
  7. include "config.inc";  
  8. mysql_connect($dbhost,$dbuser,$dbpass);  
  9. mysql_select_db($dbname);  
  10.   
  11. if(isset($_GET['Kilep']))  
  12. {  
  13. //unset($_SESSION['C_ID']);  
  14. //session_destroy();  
  15. }  
  16.   
  17.   if (isset($_POST['loginC']))  
  18.   { //Ha postolt adatokat  
  19.     //$nick = addslashes($_POST['nev']);  
  20.     //$pass = md5($_POST['jelszo']);  
  21.       
  22.     $C_ID = ($_POST['C_ID']);  
  23.     $PW = ($_POST['PW']);  
  24.   
  25.     $sql = "SELECT * FROM company ";  
  26.     $sql.= "WHERE (C_ID='".$C_ID."'";  
  27.     $sql.= " AND PW='".$PW."')";  
  28.   
  29.     $query = mysql_query($sql);  
  30.   
  31.     if (mysql_num_rows($query) !== 0)  
  32.     { //Helyes nick+pass  
  33.         session_start();  
  34.       $_SESSION['C_ID'] = $_POST['C_ID'];  
  35.       $_SESSION['belepett'] = true;  
  36.       echo "Belépett";  
  37.   
  38.       header("Location: frame.php");  
  39.     }  
  40.   
  41.     else  
  42.     {//Hibás nick+pass  
  43.       print "hibás nick/pass";  
  44.     }  
  45.   }  
6

Nem

janoszen · 2009. Szep. 29. (K), 19.08
Alapvetően ez nem fog működni. A dolog úgy működik, hogy a session sütinek bármiféle kimenet (HTML kód, stb) ELŐTT kell kimennie. Az ob_start() arra jó, hogy nem küldi el ténylegesen a kimenetet, hanem megvárja a flusht. Az ilyen jellegű használata tulajdonképpen egy hack.

Namost, az ob_start()-nak mindenféle kimenet előtt kell szerepelnie, különben pont nem fog használni. Javaslom viszont, ha már átszervezed a kódodat, akkor költöztesd a session_start-ot az elejére, másrészt a HTML generálást szedd külön fájlba.
8

átszervezés

a.d.a.m · 2009. Szep. 29. (K), 22.11
proclubnak igazsága van, a legegyszerűbb jelen esetben a kód átszervezése. Egyébként csupán ha a session_start()-ot a kód elejére helyezed nem segítene (szerintem), hiszen a 38. sor előtt már megy ki kimenet (html is / php is).
Érdemes elolvasgatni a korábban belinkelt oldalakat, ott találsz hasznos dolgokat a kódszervezés kapcsán is.

Egyébként két megjegyzést fűznék a kódodhoz, ha megengeded:
1. Ha jól láttam nincs lekezelve a bejövő adat szűrése, escape-elése, hanem közvetlenül SQL lekérdezésbe helyezed, ez eléggé támadhatóvá teszi a rendszered.
2. Nem kezeled azt a kivételt, ha mysql_num_rows($query) > 1, vagyis ha több sor is megfelel a lekérdezésnek az adatbázisban (ez egy bejelentkezésnél nem túl biztonságos állapot, hisz ilyenkor vannak azonos felhasználónév/jelszó párost birtokló userek), ez valamennyire összefügg a korábbival felvetéssel, mert együtt lehetőség van SQL Injection-re (Pl. próbáld ki ezt a $_POST['C_ID']: barmi' OR 1 = '1').
9

Köszi! értem

Petrusz · 2009. Szep. 29. (K), 22.56
A bejelentkezést gondoltam későbbre hagyom .. ez még csak egy próba. Eddig csak localhoston csináltam ott jók voltak a sessionok meg ilyesmik, de fw-n már nem. Viszont kiszedtem a HTML részeket és úgy tűnik már nem akad meg a munkafolyamat viszont van egy rész amit be se tölt a progim... gyakorlatilag mikor az egyik frame-ben lefut valami akkor egy javascriptes location egy másik framben lefuttat egy másik kódot, localhoston fut feltéve az fw.hu ra viszont meg se jelenik
  1. <script language="javascript">  
  2. top.frames["list"].location.href ="lista_partner.php";  
  3. </script>   
soha nem tanultam programozni.. gondolom ez látszik. Ami most felettébb kiakasztott, hogy nagy nehezen összehozok valamit localhoston müxik... feltöltöm és újrakezdhetem a dolgokat... miért van az hogy valami localon olyan szép máshol meg nem
10

nagy nehezen összehozok

gex · 2009. Szep. 29. (K), 23.34
nagy nehezen összehozok valamit localhoston müxik...
ott se működik csak valószínűleg nem íratod ki a hibákat, legalábbis a warningokat biztosan nem.
11

pedig müködik...

Petrusz · 2009. Szep. 30. (Sze), 12.10
az ha egy javascript lefut localhoston, de a freewebre átmásolva nem azt nem kitaláltam
12

link?

gex · 2009. Szep. 30. (Sze), 12.12
link? a javascript a kliensen fut, maximum azok a frame-ek zavarhatnak be.
13

weberp.fw.hu => eclient

Petrusz · 2009. Szep. 30. (Sze), 13.16
belépés mint cég, majd törzs és főkönyv. Van 4 frame: a jobb oldali a fő menü (még nem mindegyik elérhető) középső felső az almenü, középső frame az új tétel felvitele és az alsó lenne a céghez tartozó lista amit a középső frame frissítésekor egy javascriptnek fel kellene frissítenie.

Ha adsz egy emailt akkor átküldhetem a teljes programot a szükséges mysql táblákkal amit sql ben le kell futtatni
14

Hiba

a.d.a.m · 2009. Szep. 30. (Sze), 14.42
az első, amit már fent is írtam, nem lehet kimenet a header előtt, mert az hibát generál (ez nem csak a cookie-kra igaz):
  1. Belépett  
  2. Warning: Cannot modify header information - headers already sent by (output started at /disk/raid4/w/e/weberp/eclient/index.php:53) in /disk/raid4/w/e/weberp/eclient/index.php on line 55  
A fenti hibát az generálta, hogy frissítettem az oldalt. Nem is sikerült belépni újra, csak a süti törlése után.

A kérdésedre, nagy valószínűséggel a hiba oka az fw. Ha megnézed az oldalad forrását, láthatod hogy az egészet az fw egy keretbe illesztette (a hirdetés miatt).
Próbáld így:
  1. parent.document.getElementById("list")  
természetesen a frame id-je list legyen vagy így:
  1. parent.frames["list"]  
Vagy frissítheted azt a keretet automatikusan is. Ehhez javaslom a HTML és a Javascript referenciák áttanulmányozását.
15

Hibát hibára halmozok

Petrusz · 2009. Szep. 30. (Sze), 15.45
Tehát ha nem lehet kimenet a header előtt akkor a sessiont át kell tenni a header után... lehet hogy furcsát kérdezek.. de a header átirányítja a program futását egy másik php-nak ezáltal a session hogy fut le, már ha a header után teszem
a másik kérdésem az volna, hogy a parent.document és frames-t most a javasciptbe írjam be a top.frames helyére?
Az automatikus frissítéssel az a bajom, hogy a framekbe lévő kimeneti php-t cserélgetem attól függően, hogy melyik menühöz melyik mysql tábla listája tartozik - eltérő megjelenítéssel

Alapvetően javascript mentesre terveztem ezt az alkalmazást, de valamit nem tudok megoldani nélküle
17

továbbra sem

a.d.a.m · 2009. Szep. 30. (Sze), 16.37
úgy látom továbbra sem egyértelmű a dolog. A session_start alapvetően nem eredményez kimenetet (ha csak nem hibás a kódod, vagy iratod szándékosan kimenetre a visszatérési értéket) így az bátran ott lehet a header függvényhívás előtt, a script elején. A header azért nem működik mert az előtte lévő sorban van egy echo.

Érdemes lenne átolvasnod a PHP manuált (a neten találhatsz magyar nyelvű változatot is, ha hadilábon állsz az angollal) és a korábban belinkelt oldalakat, forrásokat. Nem véletlenül hivatkozom/hivatkozunk rájuk több soron.

A második kérdésre a válasz: igen.

Ami a javascript mentes megoldást illeti, azzal is megvalósítható a dolog frame-ek nélkül, egyszerűbben, tisztán PHP alapokon. De ugyanilyen elegáns javascriptes megoldás lehet pl a jquery+Ajax páros használata is. A te megközelítésed, szerintem (bár lehet hogy a többiek ezt máshogy látják) nem a legmegfelelőbb a feladathoz (ha jól láttam valamiféle könyvelőprogramot szeretnél írni).
18

CSS

Petrusz · 2009. Okt. 2. (P), 12.09
Amennyiben kiszedem a php elejéről a HTLM be ágyazott header css-t hogy ne küldjön adatokat ezzel blokkolva a sessiont, hogyan tudok mégis használni stíluslapokat a php kódban. Vagy ebben az esetben soronként kezelem a szineket
19

Ahogy proclub is írta:

a.d.a.m · 2009. Okt. 2. (P), 13.46
a HTML generálást szedd külön fájlba.
20

megpróbáltam

Petrusz · 2009. Okt. 2. (P), 23.32
include "html.inc";

mert ebben az esetben is probléma van a headerrel, segíts hogy kell ezt értelmeznem.

Köszönöm!

közben a html-t át tettem a session start() után és akkor gond nélkül megy a css és nem is foglalja le a headert- bagy csak valami más a logikája az egésznek... nem tudom
21

Kályhától

janoszen · 2009. Okt. 3. (Szo), 09.49
Akkor induljunk el a kályhától. Csinálsz egy fájlt, ami csak a HTML szerkezetet tartalmazza egy kevés tartalommal és nagyon nagyon kevés működési logikával. Legyen ennek a neve: template.php Pl így:
  1. <html>  
  2.  <head>  
  3.   <title>Az én oldalam</title>  
  4.  </head>  
  5.   
  6.  <body>  
  7.   <?php echo($content); ?>  
  8.  </body>  
  9. </html>  
Ezek után csinálsz egy templates mappát, amibe a különféle oldalakat be lehet rámolni. A gyakorlat kedvéért készítsük el a következő fájlokat:

index.php
  1. <form action="/?page=login" method="post">  
  2. <?php if (isset($message)) echo($message); ?>  
  3. Felhasználónév: <input type="text" name="user" value="<?php if (isset($user)) echo(htmlspecialchars($user)); ?>" /><brbr =>  
  4. Jelszó: <input type="password" name="password" value="" /><br />  
  5. <input type="submit" value="Mehet" />  
  6. </form>  
secret.php
  1. Nagyon titkos oldal.  
Ezek után készítsük el a pages mappát, amiben a működési logika fog lakni a következő fájlokkal:

index.php
  1. <?php  
  2. $data = array();  
  3. if (isset($_SESSION['message']))  
  4. {  
  5.  $data['message'] = $_SESSION['message'];  
  6.  unset($_SESSION['message']);  
  7. }  
  8. if (isset($_SESSION['formdata']['user']))  
  9. {  
  10.  $data['user'] = $_SESSION['formdata']['user'];  
  11.  unset($_SESSION['formdata']);  
  12. }  
  13.   
  14. $content = renderTemplate("index"$data);  
login.php
  1. <?php  
  2.   
  3. $login = false;  
  4. if (isset($_POST['user']) && isset($_POST['password']))  
  5. {  
  6.  $query = "SELECT * FROM company ";  
  7.  $query .= "WHERE (C_ID='".mysql_real_escape_string($_POST['user'])."'";    
  8.  $query .= " AND PW='".mysql_real_escape_string($_POST['password'])."')"; ";  
  9.  $result = mysql_query($sql);    
  10.  if (mysql_num_rows($result) !== 0)    
  11.  {  
  12.   $login = true;  
  13.  }  
  14. }  
  15.   
  16. if (!$login)  
  17. {  
  18.  $_SESSION['message'] = 'Belépés sikertelen.';  
  19.  $_SESSION['formdata'] = array();  
  20.  if (isset($_POST['user']))  
  21.  {  
  22.   $_SESSION['formdata']['user'] = $_POST['user'];  
  23.  }  
  24.  $_SESSION['C_ID'] = $_POST['user'];  
  25.  $_SESSION['belepett'] = true;  
  26.  header('Location: /');  
  27. else {  
  28.  header('Location: /?page=secret');  
  29. }  
  30. $useTemplate = false;  
secret.php
  1. <?php  
  2. if (isset($_SESSION['user']))  
  3. {  
  4.  $content = renderTemplate('secret');  
  5. else {  
  6.  $_SESSION['message'] = "Az oldal megtekintéséhez belépés szükséges!";  
  7.  header("Location: /");  
  8.  $useTemplate = false;  
  9. }  
Ezek után már csak a varázslatot megcsináló fő részt kell megírni, avagy a gyökérben levő index.php-t:
  1. <?php  
  2.   
  3. function renderTemplate($name$data = array())  
  4. {  
  5.  $file = dirname(__FILE__) . "/templates/" . $name . ".php";  
  6.  if (!preg_match(/^[a-zA-Z0-9]+$/, $name) || !file_exists($file))  
  7.  {  
  8.   return false;  
  9.  }  
  10.  extract($data);  
  11.  ob_start();  
  12.  include($file);  
  13.  $content = ob_get_contents();  
  14.  ob_end_clean();  
  15.  return $content;  
  16. }  
  17.   
  18. function loadPage($name)  
  19. {  
  20.  $file = dirname(__FILE__) . "/pages/" . $name . ".php";  
  21.  if (!preg_match(/^[a-zA-Z0-9]+$/, $name) || !file_exists($file))  
  22.  {  
  23.   return false;  
  24.  }  
  25.  include($file);  
  26.  if (isset($content))  
  27.  {  
  28.   if (!isset($useTemplate) || !$useTemplate())  
  29.   {  
  30.    echo($content);  
  31.   } else {  
  32.    include(dirname(__FILE__) . "/template.php");  
  33.   }  
  34.  }  
  35. }  
  36.   
  37. include "config.inc";  
  38. mysql_connect($dbhost,$dbuser,$dbpass);  
  39. mysql_select_db($dbname);  
  40.   
  41. session_start();  
  42.   
  43. if (!isset($_GET['page']))  
  44. {  
  45.  $_GET['page'] = "index";  
  46. }  
  47.   
  48. loadPage($_GET['page']);  
Megmondom őszintén, nem futtattam le, szóval lehet, hogy el van csettintve, de a cél inkább az volt, hogy lásd a megoldást.

Összegezve a megoldást:
  • Az index.php megkapja a page változót, ami alapján (természetesen ellenőrizve) a pages mappából beránt egy oldalt.
  • Az oldal a maga részéről beránthat egy templatet. (Nem, ez nem MVC konform, de legalább egyszer.)

Meg van oldva a problémád és ráadásul szét van darabolva ehető egységekre a kódod.
16

Ez is jó lehet?

Petrusz · 2009. Szep. 30. (Sze), 16.03
  1. parent.list.location="lista_partner.php"