matse Geschrieben 23. August 2010 Geschrieben 23. August 2010 Ich versuche PHP und MySQL zu lernen, mit dem Buch von M.Kofler und B.Öggl (von Addison-Wesley-Verlag). Es gibt dort ein Beispiel eines Buchungssystems für Geräte, welches ich nicht zum Laufen bringen kann. Ich hoffe, jemand kann es mir erklären, wo meine Fehler liegen... Im Browser bekomme ich folgende Fehlermeldung: Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at C:\xampp\htdocs\benq\index.php:2) in C:\xampp\htdocs\benq\main.php on line 3 Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at C:\xampp\htdocs\benq\index.php:2) in C:\xampp\htdocs\benq\main.php on line 3 Parse error: syntax error, unexpected T_STRING, expecting T_VARIABLE in C:\xampp\htdocs\benq\vorrat.php on line 6 Hier die Dateien: index.php <?php require_once(dirname(__FILE__)."/main.php"); $elements = vorrat::getAll(); if ($elements == FALSE) { header("Location: add.php"); exit(); } html_start("Reservierungssystem"); foreach($elements as $r) { echo "<option value='{$r->id}'>{$r->name}</option>\n"; } ?>[/PHP] [b]main.php[/b] [PHP]<?php session_start(); //dritte Zeile function __autoload($class_name) { require_once(strtolower(dirname(__FILE__)."/$class_name.php")); } ?> vorrat.php <?php abstract class vorrat { public $id; public $name; public reservations = array(); //6.Zeile public static $valid = array("benq" => "benq", "asus" => "asus"); public abstract function showCreate(); // Zeigt ein HTML-Formular zum Erstellen einer neuen Klasse. // Jede Unterklasse muss diese Funktion ueberschreiben.[/PHP] Zitieren
flashpixx Geschrieben 23. August 2010 Geschrieben 23. August 2010 Die Meldung bedeutet, dass der Header schon gesendet wurde. Der Header darf nur einmal gesendet werden und das bevor irgendwas anderes gesendet wurde Zitieren
matse Geschrieben 24. August 2010 Autor Geschrieben 24. August 2010 Und was sollte ich nun in meinem PHP-Code ändern, damit es funktioniert? Zitieren
Callam Geschrieben 24. August 2010 Geschrieben 24. August 2010 hi, nimm mal session_start() aus der main.php raus und setz es in der index.php vor require_once(dirname(__FILE__)."/main.php"); Zitieren
matse Geschrieben 24. August 2010 Autor Geschrieben 24. August 2010 hi, nimm mal session_start() aus der main.php raus und setz es in der index.php vor require_once(dirname(__FILE__)."/main.php"); Das Umsetzen hat nicht geholfen. Ich habe aber den session_start() auskommentiert und bekomme diese Meldung nicht mehr. Was soll ich aber mit der Datei vorrat.php machen? Anscheinend mag der Compiler die Zeile public reservations = array(); nicht. Diese ist aber eins zu eins vom Buch kopeirt. Ich verstehe nicht was da falsch ist. Zitieren
Reinhold Geschrieben 24. August 2010 Geschrieben 24. August 2010 public reservations = array(); nicht. Diese ist aber eins zu eins vom Buch kopeirt. Ich verstehe nicht was da falsch ist. mal so eben aus der hohlen Hand: public $reservations = array(); Zitieren
matse Geschrieben 24. August 2010 Autor Geschrieben 24. August 2010 Danke Reinhold! Ich bekomme jetzt aber eine neue Meldung, die ich nicht verstehe Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\benq\index.php:2) in C:\xampp\htdocs\benq\index.php on line 8 Hier der PHP-Code index.php <?php //session_start(); require_once(dirname(__FILE__)."/main.php"); $elements = vorrat::getAll(); if ($elements == FALSE) { header("Location: add.php"); //8. Zeile exit(); } html_start("Reservierungssystem"); foreach($elements as $r) { echo "<option value='{$r->id}'>{$r->name}</option>\n"; } ?>[/PHP] [b]add.php[/b]. Sieht etwas komisch aus. Ich denke, da werden sich auch ein Paar Fehler auffinden. [PHP]<select name="vorrat"> <?php foreach (vorrat::$valid as $k=>$v) { echo "<option value='$k'>$v</option>\n"; } ... Zitieren
etreu Geschrieben 24. August 2010 Geschrieben 24. August 2010 Ich finde die Fehlemeldung zwar nicht ganz passend, da der Location-Header eigentlich auf die Seite weiterleiten sollte, aber gut. Du darfst keine Ausgaben machen, bevor du die Session startest. Entweder du startest die Session als erstes, du arbeitest mit ob_start() oder du beachtest die Reihenfolge. HTML-Code sind Ausgaben! Zitieren
matse Geschrieben 25. August 2010 Autor Geschrieben 25. August 2010 Tut mir Leid, aber ich verstehe nicht wirklich, was du meinst. Wenn ich die Zeile mit session_start(); in index.php (oder main.php, wie im Original) nicht auskommentiere, dann bekomme ich eine Fehlermeldung (siehe mein erster Beitrag). Und die Funktion ob_start() kenne ich nicht. Ich habe zwar im php.manual die Definition durchgelesen, weiß aber nicht, wie ich diese Funktion in mein Programm richtig einbaue, und auch welche Parameter sie braucht. Für eine detailliertere Hilfe wäre ich sehr dankbar. Gruß, matse Zitieren
etreu Geschrieben 25. August 2010 Geschrieben 25. August 2010 Die Funktion session_start setzt HTTP-Header. Erfolgt bereits vorher eine Ausgabe (z.B. eine PHP-Fehlermeldung oder HTML-Code) kommt die Fehlermeldung die dir bereits bekannt ist. -> Jede Ausgabe wird im Normalfall umgehend an den Browser geschickt. ob_start() erlaubt es dir die Ausgaben zwischenzuspeichern. Damit kannst du zu einem späteren Zeitpunkt noch Header setzen. Du kannst sogar den bereits generierten Inhalt noch mal ändern. Die Ausgabe wird dann via ob_end_flush() ausgelöst. Die Parameter sind optional. Was verstehst du denn daran nicht? Aufbau der Skripte: ob_start(); // dein code ob_end_flush(); [/PHP] Zitieren
matse Geschrieben 25. August 2010 Autor Geschrieben 25. August 2010 Meinst Du das so <?php //session_start(); ob_start(); require_once(dirname(__FILE__)."/main.php"); $elements = vorrat::getAll(); if ($elements == FALSE) { header("Location: add.php"); //Zeile 11 exit(); } html_start("Reservierungssystem"); foreach($elements as $r) { echo "<option value='{$r->id}'>{$r->name}</option>\n"; } ob_end_flush(); ?>[/PHP] Funktioniert leider auch nicht. Bekomme wieder die Meldung [color=Navy]Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\benq\index.php:2) in C:\xampp\htdocs\benq\index.php on line 11[/color] Zitieren
etreu Geschrieben 25. August 2010 Geschrieben 25. August 2010 Hast du noch irgendwelche Zeichen in deiner index.php vor der php processing instruction zu stehen? Zitieren
matse Geschrieben 26. August 2010 Autor Geschrieben 26. August 2010 main.php <?php //session_start(); function __autoload($class_name) { require_once(strtolower(dirname(__FILE__)."/$class_name.php")); } ?>[/PHP] session_start(); habe ich auskomentiert, denn es funktionierte nicht (siehe mein erster Beitrag). Im Buch war hier der session_start() und nicht in index.php Zitieren
Reinhold Geschrieben 26. August 2010 Geschrieben 26. August 2010 Moin, wie auch immer, der Fehler besagt eindeutig, das du versuchst einen Header zu senden, nachdem bereits Ausgaben erfolgt sind. uU kannst du ja mal die vollständigen php-Dateien hier einstellen, dann kann man evtl. etwas erkennen. Reinhold Zitieren
matse Geschrieben 26. August 2010 Autor Geschrieben 26. August 2010 Also, hier meine PHP-Dateien. index.php und main.php sind oben zu sehen add.php <select name="vorrat"> <?php foreach (vorrat::$valid as $k=>$v) { echo "<option value='$k'>$v</option>\n"; } if ($send != '') { $r = new $res(0); html_start("Hinzufuegen eines Artikels"); echo "<h2>Hinzufügen eines Artikels: $res</h2>\n"; printf("<form method='GET' action='%s'>\n",$_SERVER["PHP_SELF"]); $r->showCreate(); echo "<input type='submit' name='add' value='Hinzufügen'>\n"; html_end(); exit(); } if ($add != '') { $o = new $object(time()); foreach($_GET as $k=>$v) { $o->$k = $v; } try { if ($o->name == '') $o->name = $o->id; $o->save(); html_start("Neues Artikel hinzugefügt"); echo "<h2>Neues Artikel hinzugefügt: ID: {$o->id}</h2>\n"; echo "<a href='book.php?id={$o->id}'>Termine reservieren</a>.\n"; html_end(); exit(); } catch (Exception $e) { html_start("Fehler beim Hinzufügen"); echo "<h2>Es ist ein Fehler aufgetreten: ".$e->getMessage()."</h2>\n"; } } ?>[/PHP] [b]reserved.php[/b] [PHP]<?php class reserved { public $start; public $end; public $user; public function __construct($start, $end, $user) { if ($start > $end) throw new Exception("Endzeit vor dem Beginn"); $this->start = $start; $this->end = $end; $this->user = $user; if ($this->getDuration() > 3600*24*62) throw new Exception("Keine Buchungen ueber zwei Monate"); } public function getDuration() { return ($this->end - $this->start); } public function isBusy($from, $to) { // gibt TRUE zurück, wenn das Objekt zwischen $from und $to bereits gebucht ist if (($this->start <= $from && $this->end >= $from) || ($this->start <= $to && $this->end >= $to) || ($from <= $this->start && $to >= $this->end)) return true; else return false; } } class DateFormatException extends Exception { public function __construct($msg); { parent::__construct($msg); } public function showHelp() { echo "<p class = 'hint'>". "<a href = 'http://www.gnu.org/software/tar/manual/html_chapter/tar_7.html'>". "Zur Liste</a> der unterstützten Datumsformate.</p>\n"; } public funtion __toString() { return "<p class = 'error'>".$this->getMessage()."(".__CLASS__.").</p>\n"; } } ?> vorrat.php <?php abstract class vorrat { public $id; public $name; public $reservations = array(); public static $valid = array("benq" => "benq", "asus" => "asus"); public abstract function showCreate(); // Zeigt ein HTML-Formular zum Erstellen einer neuen Klasse. // Jede Unterklasse muss diese Funktion ueberschreiben. public function book($s,$e){ if ($s == '' || $e == '') throw new DateFormatException("Leeres Datum"); $start = strtotime($s); $end = strtotime($e); $user = $_SERVER["REMOTE_ADDR"]; if ($start == -1 || $end == -1) throw new DateFormatException("Fehler bei der Zeitumwandlung"); $res = new reserved($start, $end, $user); if ($this->isBooked($start,$end)) throw new Exception("{$this->name} ist zu dieser Zeit bereits belegt."); $this->reservations[$start] = $res; } public function isBooked($start, $end = NULL) { if ($end == NULL) $end = $start + 1; if (count($this->reservations) > 0){ foreach ($this->reservations as $r) { if ($r->isBusy($start, $end)) return true; } } return false; } public function save() { $_SESSION['vorrat'][$this->id] = $this; return true; } public static function clearAll() { unset($_SESSION['vorrat']); return true; } public static function getAll() { if (property_exists('vorrat', $_SESSION)) return $_SESSION['vorrat']; else return false; } public static function getById($id) { if (array_key_exists($id, $_SESSION['vorrat'])) return $_SESSION['vorrat'][$id]; else throw new Exception("Id nicht gefunden"); } } class benq extends vorrat { public $operatingSystem = ''; public $ram = ''; public function __construct($id) { parent::__construct($id); } public function showCreate() { echo "<table border = '1'>\n"; $this->showTextFeature('Name', 'name'); $this->showTextFeature('Betriebssystem', 'operatingSystem'); $this->showTExtFeature('RAM', 'ram'); echo "</table>\n"; echo "<input type = 'hidden' name = 'object' value = 'BENQ'>\n"; } } class asus extends vorrat { public $operatingSystem = ''; public $ram = ''; public function __construct($id) { parent::__construct($id); } public function showCreate() { echo "<table border = '1'>\n"; $this->showTextFeature('Name', 'name'); $this->showTextFeature('Betriebssystem', 'operatingSystem'); $this->showTExtFeature('RAM', 'ram'); echo "</table>\n"; echo "<input type = 'hidden' name = 'object' value = 'ASUS'>\n"; } } ?> [/PHP] [b]DateFormatException.php[/b] [PHP]<?php class DateFormatException extends Exception { public function __construct($msg); { parent::__construct($msg); } public function showHelp() { echo "<p class = 'hint'>". "<a href = 'http://www.gnu.org/software/tar/manual/html_chapter/tar_7.html'>". "Zur Liste</a> der unterstützten Datumsformate.</p>\n"; } public funtion __toString() { return "<p class = 'error'>".$this->getMessage()."(".__CLASS__.").</p>\n"; } } ?> book.php <?php if ($id == '' || $id == false) { header("Location: index.php"); } try { $r = vorrat::getById($id); } catch (Exception $e) { html_start(); echo "<p class='error'>Der gewünschte Artikel konnte nicht gefunden werden\n"; html_end(); exit(); } $r->showAddReservation(); if ($reserve != '') { $from = array_item($_GET, 'from'); $to = array_item($_GET, 'to')); try { $r->book($from, $to); $r->save(); } catch (DateFormatException $e) { echo $e; $e->showHelp(); } catch (Exception $e) { printf("<p class='error'>%s</p>\n", $e->getMessage()); } } $r->showBooked(); ?>[/PHP] Zitieren
etreu Geschrieben 30. August 2010 Geschrieben 30. August 2010 Wie sieht der generierte Quelltext aus, der an den Browser geschickt wird? Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.