Hallo,
ich weiß echt nicht warum aber wenn ich einen Fehler mit getSettings provozieren will dann bekomme ich "Fatal error: Using $this when not in object context in C:\xampp\htdocs\www\9mango\core\classes\Core.php on line 60" langsam kenne ich mich nicht mehr aus…
ich hoffe ihr könnt mir helfen
Db.php
[CODE]
//Namespace
namespace core\classes;
use core\classes\exceptions\DatabaseErrorHandler as DatabaseErrorHandler;
//Class
class Db extends \MySQLi {
/* Constructor */
public function __construct() {
$this->connect();
}
/* Datenbankverbindung */
public function connect()
{
try
{
@parent::connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
if (mysqli_connect_errno()){
throw new DatabaseErrorHandler(mysqli_connect_error(), mysqli_connect_errno());
}
}
catch (DatabaseErrorHandler $e)
{
$e->_buildErrorPage();
}
}[/CODE]Core.php
[CODE]
/* Benötigte Klassen werden instanziert */
private function loadClasses() {
$this->_db = Registry::get("db");
}
/* SETTINGS LADEN */
public function getSettings($name, $typ) {
// Query vorbereiten und an die DB schicken
try {
$sql = "SELECT * FROM ".DB_PRÄFIX."settings WHERE name='$name' and typ='$typ'";
[B] $result = $this->_db->query($sql); // ich bin Zeile 60[/B]
if($result) {
while($row = $result->fetch_object())
{
return $row->value;
}
} else {
throw new SystemErrorHandler("Die gesuchte Einstellung wurde nicht gefunden", 1);
}
}
catch (DatabaseErrorHandler $e) {
$e->_buildErrorPage();
}
catch (SystemErrorHandler $e) {
$e->_buildErrorPage();
}
$result->_db->close();
}
[/CODE]mfg
$this bereitet immer Probleme, weil this (ohne $) gibt es ja auch ;D einfach $this in $that ändern und es müsste funktionieren (jedenfalls tuts das bei mir immer xD)
$result = $this->_db->query($sql); // ich bin Zeile 60
: ) ich werde sie noch bissl besser markieren(geht das überhaupt innerhalb eines code tags in vb? xD)
einfach $this in $that ändern und es müsste funktionieren
Rufst du getSettings vielleicht statisch (Klasse::getSettings) auf?
Für mich sieht der gezeigte Code okay aus (oder er würde glaube ich zumindest nicht die beschriebene Fehlermeldung liefern). Ich fürchte, da bräuchte man für eine Antwort im Zweifel mehr Kontext.
Lass dir Objekte/Variablen an geeigneten Stellen per var_dump() ausgeben. Dann kommst du vielleicht auf die Spur, welcher Code wo nicht mehr erreicht wird oder welche Variable wann welchen Wert hat, obwohl sie eigentlich einen anderen haben sollte.
jetzt habe ich nur noch das Problem mit der nicht ausgegebenen Exception : (
[CODE]/* SETTINGS LADEN */
public function getSettings($name, $typ) {
// Query vorbereiten und an die DB schicken
try {
$sql = "SELECT * FROM ".DB_PRÄFIX.„settings WHERE name=‚$name‘ and typ=‚$typ‘“;
$result = $this->_db->query($sql);
Du machst das ein bisschen kompliziert. Die Idee wäre, zentral einen Error Handler zu definieren, der alle Exceptions bearbeitet, die nicht vorher gefangen wurden.
Das heißt, du kannst einfach fangen, was du fangen willst, und alle anderen Fehler stumpf ignorieren für den Standard-Handler.
[php]<?php
class ErrorController
{
public function errorAction($exception)
{
echo ‚
Du willst ja offensichtlich in manchen Fällen eine eigene Fehlerseite erzeugen ($e->_buildErrorPage();). Den wiederkehrenden Aufruf der entsprechenden Funktion kannst du dir sparen, indem du einmal eine Methode angibst, die alle nicht bearbeiteten (= gefangenen) Fehler behandelt. Du würdest in deiner getSettings-Methode zum Beispiel den try-catch-Block weglassen und die Ausführung käme dennoch automatisch bei ErrorController::errorAction an, weil die Exceptions vorher nicht gefangen werden.
Achso, wenn ich den set Exception Handler setze sollte dies Global z.B. in der Bootstrap oder in der jeweiligen Datei geschehen? Wenn ja sollte dies dann so eine Art Top Level Handler sein der z.B. nicht gefangene Exceptions „aufnimmt“? Soll ich auf Try and Catch ganz verzichten? Gibt es für diese Methode irgendwelche Nachteile?
Achso, wenn ich den set Exception Handler setze sollte dies Global z.B. in der Bootstrap oder in der jeweiligen Datei geschehen?
Ja, genau. Bootstrap.
Wenn ja sollte dies dann so eine Art Top Level Handler sein der z.B. nicht gefangene Exceptions „aufnimmt“?
…und aus der Exception dann eine Fehlerseite generiert wie eine ganz normale Action eine normale Seite generiert. Es war mein Eindruck, dass du genau sowas machen wolltest mit $e->_buildErrorPage().
Soll ich auf Try and Catch ganz verzichten? Gibt es für diese Methode irgendwelche Nachteile?
Abfangbare Fehler, die nicht zum Abbruch der Ausführung des Scripts führen müssen (bzw. nicht zur Ausgabe einer Fehlerseite), kannst und solltest du auch weiterhin mit try-catch behandeln.
Edit: Der globale Error/Exception Handler ist einfach eine mit weniger Redundanz und Logikcode verbundene Art und Weise, die Fehlerseiten-Funktionalität umzusetzen.
Jetzt hab ich die Klasse etwas geändert,… ich musste den __constructor in set_exception_handler angeben ansonsten würde es ja nicht parent::construct aufrufen… nun weiß ich bald nicht mehr ob das so elegant genug bzw. eine gute Lösung ist, vl kannst mir ja (wiedereinmal) helfen
Ausschnitt aus Bootstrap:
[CODE]use core\classes\exceptions\SystemErrorHandler as SystemErrorHandler;
Der „Fehler“ ist, SystemErrorHandler von Exception abzuleiten. Das ergibt inhaltlich auch keinen Sinn.
Ich habe noch mal versucht, das Beispiel für deine Klassen umzuschreiben, vielleicht ist das offensichtlicher.
[php]<?php
class SystemErrorHandler
{
public function _buildErrorPage(Exception $exception)
{
$page = new View();
$page->setView(„SystemErrorHandler“);
$page->assign(‚message‘,$exception->getMessage());
$page->assign(‚code‘,$exception->getCode());
$page->assign(‚file‘,$exception->getFile());
$page->assign(‚line‘,$exception->getLine());
$page->assign(‚trace‘,$exception->getTraceAsString());
$page->parseView();
}
}
class DatabaseException extends Exception{}
class SystemException extends Exception{}
class View
{
protected $data = array();
public function setView($script){}
public function assign($key, $value){$this->data[$key]=$value;}
public function parseView()
{
echo ‚
Debug
‘;
print_r($this->data);
}
}
class Foo
{
/* SETTINGS LADEN */
public function getSettings($name, $typ) {
// Query vorbereiten und an die DB schicken
//$sql = "SELECT * FROM ".DB_PRÄFIX."settings WHERE name='$name' and typ='$typ'";
//$result = $this->_db->query($sql);
$result = false;
if($result) {
while($row = $result->fetch_object())
{
return $row->value;
}
} else {
throw new SystemException("Die gesuchte Einstellung wurde nicht gefunden", 1);
}
}
Zunächst möchte ich dir mal danken, dass du mir hilfst^^
Nun ich habe das jetzt so umgesetzt wie du es mir erklärt hast jedoch gibt mir PHP einen Fehler aus
Catchable fatal error: Argument 1 passed to core\classes\errorhandler\SystemErrorHandler::_buildErrorPage() must be an instance of core\classes\errorhandler\Exception, instance of core\classes\exceptions\SystemException given in C:\xampp\htdocs\www\9mango\core\classes\errorhandler\SystemErrorHandler.php on line 21
Exception meint in meinem Beispiel immer \Exception.
Eine Methodensignatur wie…
public function _buildErrorPage(Exception $exception)
…nimmt als Parameter dann jedes Objekt entgegen, das eine \Exception ist oder das von \Exception abgeleitet ist. (Die Namespace-Slashes müsstest du unter Umständen eben ergänzen.) Ganz normaler Umgang mit Vererbung.
Eigene Exceptions sollten dann logischerweise von \Exception abgeleitet werden (siehe mein Beispiel).
nun alles funktioniert soweit bis auf, dass wenn nichts gefunden wurde keine Exception geworfen wird…
[CODE] /* SETTINGS LADEN */
public function getSettings($name, $typ) {
// Query vorbereiten und an die DB schicken
$sql = "SELECT * FROM ".DB_PRÄFIX.„settings WHERE name=‚$name‘ and typ=‚$typ‘“;
$result = $this->_db->query($sql);
if($result == true) {
while($row = $result->fetch_object())
{
return $row->value;
}
} else {
throw new SystemException("Die gesuchte Einstellung wurde nicht gefunden", 1);
}
}