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:

@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?
<html>
<head>
<link rel="stylesheet" type="text/css" href="eclient.css" />
</head>

<?php
include "config.inc";
mysql_connect($dbhost,$dbuser,$dbpass);
mysql_select_db($dbname);

if(isset($_GET['Kilep']))
{
//unset($_SESSION['C_ID']);
//session_destroy();
}

  if (isset($_POST['loginC']))
  { //Ha postolt adatokat
    //$nick = addslashes($_POST['nev']);
    //$pass = md5($_POST['jelszo']);
    
    $C_ID = ($_POST['C_ID']);
    $PW = ($_POST['PW']);

    $sql = "SELECT * FROM company ";
    $sql.= "WHERE (C_ID='".$C_ID."'";
    $sql.= " AND PW='".$PW."')";

    $query = mysql_query($sql);

    if (mysql_num_rows($query) !== 0)
    { //Helyes nick+pass
        session_start();
      $_SESSION['C_ID'] = $_POST['C_ID'];
      $_SESSION['belepett'] = true;
      echo "Belépett";

      header("Location: frame.php");
    }

    else
    {//Hibás nick+pass
      print "hibás nick/pass";
    }
  }
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
<script language="javascript">
top.frames["list"].location.href ="lista_partner.php";
</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):
Belépett
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:
parent.document.getElementById("list")
természetesen a frame id-je list legyen vagy így:
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:

<html>
 <head>
  <title>Az én oldalam</title>
 </head>

 <body>
  <?php echo($content); ?>
 </body>
</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

<form action="/?page=login" method="post">
<?php if (isset($message)) echo($message); ?>
Felhasználónév: <input type="text" name="user" value="<?php if (isset($user)) echo(htmlspecialchars($user)); ?>" /><br =>
Jelszó: <input type="password" name="password" value="" /><br />
<input type="submit" value="Mehet" />
</form>
secret.php
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

<?php
$data = array();
if (isset($_SESSION['message']))
{
 $data['message'] = $_SESSION['message'];
 unset($_SESSION['message']);
}
if (isset($_SESSION['formdata']['user']))
{
 $data['user'] = $_SESSION['formdata']['user'];
 unset($_SESSION['formdata']);
}

$content = renderTemplate("index", $data);
login.php

<?php

$login = false;
if (isset($_POST['user']) && isset($_POST['password']))
{
 $query = "SELECT * FROM company ";
 $query .= "WHERE (C_ID='".mysql_real_escape_string($_POST['user'])."'";  
 $query .= " AND PW='".mysql_real_escape_string($_POST['password'])."')"; ";
 $result = mysql_query($sql);  
 if (mysql_num_rows($result) !== 0)  
 {
  $login = true;
 }
}

if (!$login)
{
 $_SESSION['message'] = 'Belépés sikertelen.';
 $_SESSION['formdata'] = array();
 if (isset($_POST['user']))
 {
  $_SESSION['formdata']['user'] = $_POST['user'];
 }
 $_SESSION['C_ID'] = $_POST['user'];
 $_SESSION['belepett'] = true;
 header('Location: /');
} else {
 header('Location: /?page=secret');
}
$useTemplate = false;
secret.php

<?php
if (isset($_SESSION['user']))
{
 $content = renderTemplate('secret');
} else {
 $_SESSION['message'] = "Az oldal megtekintéséhez belépés szükséges!";
 header("Location: /");
 $useTemplate = false;
}
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:

<?php

function renderTemplate($name, $data = array())
{
 $file = dirname(__FILE__) . "/templates/" . $name . ".php";
 if (!preg_match(/^[a-zA-Z0-9]+$/, $name) || !file_exists($file))
 {
  return false;
 }
 extract($data);
 ob_start();
 include($file);
 $content = ob_get_contents();
 ob_end_clean();
 return $content;
}

function loadPage($name)
{
 $file = dirname(__FILE__) . "/pages/" . $name . ".php";
 if (!preg_match(/^[a-zA-Z0-9]+$/, $name) || !file_exists($file))
 {
  return false;
 }
 include($file);
 if (isset($content))
 {
  if (!isset($useTemplate) || !$useTemplate())
  {
   echo($content);
  } else {
   include(dirname(__FILE__) . "/template.php");
  }
 }
}

include "config.inc";
mysql_connect($dbhost,$dbuser,$dbpass);
mysql_select_db($dbname);

session_start();

if (!isset($_GET['page']))
{
 $_GET['page'] = "index";
}

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
parent.list.location="lista_partner.php"