Malcolm Beck´s: Fehlerbehandlung in PHP mit MySQL

hi,

wenn Beispielsweise die vom Programmierer gewünschte Zeichenkodierung einer Seite nicht geladen werden kann -- warum auch immer -- sollte die Seite dann trotzdem ausgeliefert werden, eben mit einer falschen Zeichenkodierung, oder sollte man besser an dieser Stelle das Script abbrechen und dem Client eine entsprechende Meldung schicken?

Ist folgendes Szenario Sinnvoll?  (wird noch um ein kleines Script erweitert, das eventuell auftretende Fehler in der DB speichert)

  /*  
   * Zeichenkodierung auf UTF-8 setzen, wenn's nicht klappt, fehler ausgeben  
  */  
  if (!$_connect->set_charset("utf8"))  
  {  
    header("HTTP/1.1 500 Internal Server Error");  
    $Error = sprintf('<p>Ein fehler ist beim laden der Zeichenkodierung UTF-8 aufgetreten: <strong>%s</strong></p>', $_connect->error;  
    $template->assign($Error);  
  }  
  /*  
   * Wenn Zeichenkodierung OK, SELECT-Statement abarbeiten  
  */  
  else if ($content = $_connect->query($SELECT))  
  {  
    if ($row = $content->fetch_assoc())  
    {  
      header("HTTP/1.1 200 ok");  
      $template->assign($row);  
    }  
    else  
    {  
      /*  
       * Wenn keine Inhalte gefunden werden, error 404 melden  
      */  
      header("HTTP/1.1 404 not found");  
      $Error = '<p>Die angegebene Seite konnte nicht gefunden werden.';  
      $template->assign($Error);  
    }  
  }  
  else  
  {  
    /*  
     * Sonstige fehler, wenn eine Tabelle oder ein Feld nicht gefunden werden  
    */  
    header("HTTP/1.1 500 Internal Server Error");  
    $Error = sprintf('<p>Ein fehler ist aufgetreten: <strong>%s</strong></p>', $_connect->error;  
    $template->assign($Error);  
  }

In diesem Zusammenhang würden mich auch die jeweiligen Header-Status interessieren, die da in Frage kommen.
„Header 200“ und „Header 404“ ist klar, was aber bei den sonstigen Fehlern wie falsche Zeichenkodierung oder Fehler im SELECT-Statement?

Was tun, wenn die Verbindung zur Datenbank nicht aufgebaut werden kann? Gibt es Alternativen zu die()?
Wobei dann noch zu klären wäre, warum das Script weiter arbeiten sollte, wenn eh keine Verbindung hergestellt werden kann.

mfg

--
echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
array(2) {
  ["SELFCODE"]=>
  string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
  ["Meaningful"]=>
  string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
}
  1. Hi,

    wenn Beispielsweise die vom Programmierer gewünschte Zeichenkodierung einer Seite nicht geladen werden kann

    Seit wann werden Zeichenkodierungen "geladen"?

    -- warum auch immer -- sollte die Seite dann trotzdem ausgeliefert werden, eben mit einer falschen Zeichenkodierung, oder sollte man besser an dieser Stelle das Script abbrechen und dem Client eine entsprechende Meldung schicken?

    /*

    * Zeichenkodierung auf UTF-8 setzen, wenn's nicht klappt, fehler ausgeben
      */
      if (!$_connect->set_charset("utf8"))

      
    Ah, OK, du meinst das Aushandeln der Kodierung für die Verbindung zur Datenbank.  
      
    Nun, dass das schief geht - nachdem das Herstellen der Verbindung an sich geklappt hat - halte ich für ziemlich unwahrscheinlich. OK, es könnte mal passieren, dass man versucht eine Kodierung auszuhandeln, die die DB gar nicht kennt - aber das dürfte man wohl bereits während der initialen Testphase feststellen. Und dass die Verbindung zum DB-Server in genau dem Augenblick unterbrochen wird oder dieser selber abraucht, kann natürlich theoretisch auch nicht ausgeschlossen werden ...  
      
    
    > `    $Error = sprintf('<p>Ein fehler ist beim laden der Zeichenkodierung UTF-8 aufgetreten: <strong>%s</strong></p>', $_connect->error;`{:.language-php}  
      
    Das ist in der Detailgenauigkeit für den Nutzer der Seite uninteressant. Logge es meinetwegen intern für dich irgendwo; aber nach aussen hin reicht es m.E., ein allgemeines Datenbankproblem zu melden, wenn irgendeiner der Schritte DB-Connect, Datenbank-Auswahl oder Kodierungsaushandlung - also alle "initialen" Schritte, die immer stattfinden, bevor man irgendwas von der Datenbank abfragt oder einträgt - schief ging.  
      
    
    > In diesem Zusammenhang würden mich auch die jeweiligen Header-Status interessieren, die da in Frage kommen.  
    > „Header 200“ und „Header 404“ ist klar, was aber bei den sonstigen Fehlern wie falsche Zeichenkodierung oder Fehler im SELECT-Statement?  
      
    Den 500 Internal Server Error halte ich für solche Fälle für durchaus angebracht. Die "Definition" dieses Fehlercodes lautet "[t]he server encountered an unexpected condition which prevented it from fulfilling the request" - und genau das ist ja auch hier der Fall: Der Umstand, dass die Datenbank nicht erreichbar ist, war unerwartet, trat aber jetzt bedauerlicher Weise doch mal ein, shit happens, und hindert den Server daran, die Anfrage des Clients in der gewünschten Form zu bearbeiten.  
      
    Auch noch denkbar wäre ein 503 Service Unavailable - "The server is currently unable to handle the request due to a temporary overloading or maintenance of the server. The implication is that this is a temporary condition which will be alleviated after some delay."  
    Wir gehen ja schliesslich davon aus, dass bei unserem GuterHoster™ das Abrauchen der Datenbank nicht auf lange Sicht unbemerkt bleibt, sondern dass die Systeme schön ge-monitored werden, und sich deshalb alsbald ein Service-Wiesel höchst fleissig darum kümmern wird, dem unerfreulichen Zustand Abhilfe zu schaffen - also können wir dem Client auch mitteilen, dass wir (der Server) uns mal kurz unpässlich fühlen, aber hoffen dass wir nach einem kleinen Kräuterteechen gleich wieder auf dem Damm sind, um hübsch Konversation machen zu können.  
      
    
    > Was tun, wenn die Verbindung zur Datenbank nicht aufgebaut werden kann? Gibt es Alternativen zu `die()`{:.language-php}?  
      
    In deinem obigen Code hast du doch schon die Zuweisung eines Fehlertextes an eine Template-Variable drin stehen - das kann man gut so machen, wenn ein Fehler auftrat, diesen nicht "nackt" ausgeben, sondern durchaus im "normalen" Seitengerüst. (Das Template sollte dann nur auch checken, dass es keine anderen Daten auszugeben hat.)  
      
    
    > Wobei dann noch zu klären wäre, warum das Script weiter arbeiten sollte, wenn eh keine Verbindung hergestellt werden kann.  
      
    "Weiter arbeiten" im gewünschten Sinne (Datenbankeinträge anzeigen, anlegen, ...) kann es natürlich gar nicht - aber das heisst ja nicht, dass es nicht trotzdem \*kontrolliert\* zu einem "normalen" Ende kommen darf, anstatt mit die() ob all der Schamgefühle Harakiri zu begehen.  
      
    MfG ChrisB  
      
    
    -- 
    Light travels faster than sound - that's why most people appear bright until you hear them speak.
    
    1. hi,

      Seit wann werden Zeichenkodierungen "geladen"?

      Ich wusste nicht, wie man dass sonst nennt, „Aushandeln“ klingt gut, dass werde ich so übernehmen.

      » $Error = sprintf('<p>Ein fehler ist beim laden der Zeichenkodierung UTF-8 aufgetreten: <strong>%s</strong></p>', $_connect->error;

      Das ist in der Detailgenauigkeit für den Nutzer der Seite uninteressant.

      Das stimmt allerdings, da gehe ich wirklich zu sehr ins Detail. Mitloggen und ein kleiner Hinweis für den User ist wohl das Sinnvollste.

      Den 500 Internal Server Error halte ich für solche Fälle für durchaus angebracht. Die "Definition" dieses Fehlercodes lautet "[t]he server encountered an unexpected condition which prevented it from fulfilling the request" - und genau das ist ja auch hier der Fall: Der Umstand, dass die Datenbank nicht erreichbar ist, war unerwartet, trat aber jetzt bedauerlicher Weise doch mal ein, shit happens, und hindert den Server daran, die Anfrage des Clients in der gewünschten Form zu bearbeiten.

      Auch noch denkbar wäre ein 503 Service Unavailable - "The server is currently unable to handle the request due to a temporary overloading or maintenance of the server. The implication is that this is a temporary condition which will be alleviated after some delay."

      Der 503 klingt auch gut, den kann ich ja bei einem Fehler bei DB-Connect oder der Datenbank-Auswahl mit schicken, Fehlerhafte Kodierungsaushandlung oder SELECTs dann mit dem 500er quittieren.
      Wobei, jetzt stellt sich mir die Frage, ob eine Fehlerhafte Kodierungsaushandlung überhaupt zustande kommen kann; ich habe das Stück Code aus dem Manual, da dort ein „Eventuell“ auftretender Fehler behandelt wird, dachte ich, dass es schon richtig ist, darauf vorbereitet zu sein.

      In deinem obigen Code hast du doch schon die Zuweisung eines Fehlertextes an eine Template-Variable drin stehen - das kann man gut so machen, wenn ein Fehler auftrat, diesen nicht "nackt" ausgeben, sondern durchaus im "normalen" Seitengerüst. (Das Template sollte dann nur auch checken, dass es keine anderen Daten auszugeben hat.)

      Genau der von dir in Klammern gesetzte Punkt brachte mich auf diese Frage. Selbst wenn das Template weiss, dass es einige Dinge nicht auszugeben hat, bleiben noch die PHP-Warnungen wie Bspw. „Couldn't fetch mysqli in E:\xa“, die ich höchstens mit „error_reproting(0)“ bzw. „display_errors = OFF“ unterdrücken kann, bleibt nur die frage, ob das Ok ist.
      Es wird ja immer darauf plädiert, Fehlerfrei zu programmieren, was aber in diesem Fall ja nicht möglich ist.

      "Weiter arbeiten" im gewünschten Sinne (Datenbankeinträge anzeigen, anlegen, ...) kann es natürlich gar nicht - aber das heisst ja nicht, dass es nicht trotzdem *kontrolliert* zu einem "normalen" Ende kommen darf, anstatt mit die() ob all der Schamgefühle Harakiri zu begehen.

      Stimmt, eine nichts sagende Weiße Seite mit dem Hinweis „Unknown MySQL server host 'localhos' (11001)“ wird wohl den wenigsten Usern weiter helfen.

      mfg

      --
      echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
      array(2) {
        ["SELFCODE"]=>
        string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
        ["Meaningful"]=>
        string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
      }
      1. echo $begrüßung;

        Selbst wenn das Template weiss, dass es einige Dinge nicht auszugeben hat, bleiben noch die PHP-Warnungen wie Bspw. „Couldn't fetch mysqli in E:\xa“, die ich höchstens mit „error_reproting(0)“ bzw. „display_errors = OFF“ unterdrücken kann, bleibt nur die frage, ob das Ok ist.
        Es wird ja immer darauf plädiert, Fehlerfrei zu programmieren, was aber in diesem Fall ja nicht möglich ist.

        Es ist durchaus legitim und sogar empfehlenswert im Produktivbetrieb display_errors auszuschalten. Stattdessen sollte man einen Logmechanismus oder einen Fehlerhandler implementieren, der - wie auch immer - die aufgetretenen Fehlerdetails und kontextuelle Daten, die auf die genaue Ursache schließen lassen, an den Verantwortlichen leitet. Das error_reporting kann dabei ruhig auf hohem Level stehenbleiben. Auch der @ darf verwendet werden, wenn man eine Stelle hat, bei der man genau weiß: Hier erzeugt PHP eine Fehlermeldung, diese ist aber erwartet und die Ursache wird ausreichend behandelt.

        echo "$verabschiedung $name";

        1. hi,

          Es ist durchaus legitim und sogar empfehlenswert im Produktivbetrieb display_errors auszuschalten. Stattdessen sollte man einen Logmechanismus oder einen Fehlerhandler implementieren, der - wie auch immer - die aufgetretenen Fehlerdetails und kontextuelle Daten, die auf die genaue Ursache schließen lassen, an den Verantwortlichen leitet.

          display_errors sind bei mir Online immer auf OFF, das mitloggen muss ich noch implementieren.

          Das error_reporting kann dabei ruhig auf hohem Level stehenbleiben. Auch der @ darf verwendet werden, wenn man eine Stelle hat, bei der man genau weiß: Hier erzeugt PHP eine Fehlermeldung, diese ist aber erwartet und die Ursache wird ausreichend behandelt.

          Das ist gut zu wissen; wobei ich an sich kaum Warnings bekomme, wenn dann vielleicht mal wegen einer nicht initialisierten Variable.
          Ich hatte Gestern mal geguckt, was mir error_reporting(E_ALL | E_STRICT); so alles meldet, habe es aber schnell wieder auf E_ALL gesetzt; ich benutze Christians BBCode-Parser, der wohl einige Strict Standards-Fehler enthält, daher muss ich auf einem niedrigeren Level bleiben.

          mfg

          --
          echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
          array(2) {
            ["SELFCODE"]=>
            string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
            ["Meaningful"]=>
            string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
          }
          1. Hi,

            display_errors sind bei mir Online immer auf OFF, das mitloggen muss ich noch implementieren.

            Falls du mit "implementieren" irgendwas eigenes (aufwendiges) meinst, schau dir vorher die Konfigurationsdirektiven log_errors und error_log an (sind beide auch bspw. in .htaccess einstellbar).

            Ich hatte Gestern mal geguckt, was mir error_reporting(E_ALL | E_STRICT); so alles meldet, habe es aber schnell wieder auf E_ALL gesetzt; ich benutze Christians BBCode-Parser, der wohl einige Strict Standards-Fehler enthält, daher muss ich auf einem niedrigeren Level bleiben.

            Ja, der ist noch in PHP 4 geschrieben, wo es E_STRICT noch gar nicht gab.
            Und viele der Meldungen, die das auslöst, beruhen auch darauf, dass noch das OOP-Modell von PHP 4 benutzt wird - PHP 5 ist zwar abwärtskompatibel dazu, liefert dann bei E_STRICT aber eben entsprechend viele Meldungen.

            Das lässt sich aber auch umgehen, in dem man vor der Einbindung der stringparser_bbcode.class.php E_STRICT aus dem error_reporting-Level herausnommt, und direkt danach wieder rein. Dann kannst du deine Scripte auf Einhaltung des "strikten" Standards prüfen, und Christians Parser in seiner derzeitigen From trotzdem einbinden und nutzen.

            MfG ChrisB

            --
            Light travels faster than sound - that's why most people appear bright until you hear them speak.
            1. hi,

              Falls du mit "implementieren" irgendwas eigenes (aufwendiges) meinst, schau dir vorher die Konfigurationsdirektiven log_errors und error_log an (sind beide auch bspw. in .htaccess einstellbar).

              Danke für den Link; ich hatte mich schon mal an der PHP-eigenen Funktion probiert und es nicht hingekriegt, ich werde mir das heute Abend noch mal ansehen.

              Das lässt sich aber auch umgehen, in dem man vor der Einbindung der stringparser_bbcode.class.php E_STRICT aus dem error_reporting-Level herausnommt, und direkt danach wieder rein. Dann kannst du deine Scripte auf Einhaltung des "strikten" Standards prüfen, und Christians Parser in seiner derzeitigen From trotzdem einbinden und nutzen.

              Danke für den Hinweis, ich wusste nicht, dass ich die Stufe innerhalb des Scriptes noch ändern kann, funktioniert Tadellos, nur jetzt habe ich selbst eine Meldung, die ich nicht verstehe ;)

              Folgendes Stück macht die Probleme:

                /*  
                 * $_SERVER['REQUEST_URI'], alles nach dem Fragezeichen entfernen  
                 * also     „/seite/unterseite/begriff?parameter=test“  
                 * soll auf „/seite/unterseite/begriff“  
                 * gekürzt werden  
                */  
                define ('requestPath', preg_replace('|(.*)\?(.*)+$|', "$1", $_SERVER['REQUEST_URI']));  
                
                /*  
                 * aus dem gekürzten $_SERVER['REQUEST_URI'] möchte ich nun den letzten Wert hinter dem letzten „/“  
                */  
                define ('lastPath', array_pop (explode( '/', requestPath) ));
              

              Meldet mir der Parser „Strict Standards: Only variables should be passed by reference“, ich habe schon nach dieser Fehlermeldung gegooglet, allerdings nichts gefunden, was in meine richtung geht bzw., was ich verstehe, was ist an dem Code falsch?

              mfg

              --
              echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
              array(2) {
                ["SELFCODE"]=>
                string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
                ["Meaningful"]=>
                string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
              }
              1. Hi,

                Meldet mir der Parser „Strict Standards: Only variables should be passed by reference“, ich habe schon nach dieser Fehlermeldung gegooglet, allerdings nichts gefunden, was in meine richtung geht bzw., was ich verstehe, was ist an dem Code falsch?

                Kommt die Meldung wirklich an der Stelle, die du zitiert hast?

                Ich erinnere mich, dass ich in Christians Script eine einzige Stelle angepasst habe, weil genau diese Meldung kam (wenn das ganze als PHP 5 geparst wird).

                Da wurde an irgendeiner Stelle aus einer Methode heraus mittels return direkt ein Wert zurückgegeben (war's ein false? Ich weiss es nicht mehr so genau) - was man aber, wenn die Parameterübergabe per reference stattfindet, nicht (mehr) tun soll.
                Abhilfe schafft das Einfügen einer Variablen vor dem return, der der zurückzugebende Wert zugewiesen wird, und dann return $variable statt direkte Rückgabe des Wertes.

                MfG ChrisB

                --
                Light travels faster than sound - that's why most people appear bright until you hear them speak.
                1. hi,

                  Kommt die Meldung wirklich an der Stelle, die du zitiert hast?

                  Ja, Definitiv.
                  Die genaue Meldung lautet:

                  Strict Standards: Only variables should be passed by reference in E:\xampp\anonymous\perl\index.php on line 54

                  Und in Zeile 53 steht die Konstante:

                  define ('lastPath', array_pop (explode( "/", requestPath) ));

                  Mit der Variante, die dedlfix gepostet hat, funktioniert es.

                  Ich erinnere mich, dass ich in Christians Script eine einzige Stelle angepasst habe, weil genau diese Meldung kam (wenn das ganze als PHP 5 geparst wird).

                  Moment, ich teste nochmal kurz:

                  Ja, stimmt, man kann das error_reporting direkt nach dem einbinden der Parser-Klasse hochsetzen, dann kommt nur noch eine Meldung, mit der ich aber nichts anzufangen weiss.

                  Die Meldung lautet:

                  Strict Standards: Non-static method StringParser_Node::destroyNode() should not be called statically, assuming $this from incompatible context in E:\xampp\anonymous\perl\configs\my_libs\bbcode_handling\stringparser.class.php on line 357

                  Zeile 356
                  $res = StringParser_Node::destroyNode ($this->_root);

                  Ich habe schon versucht, den Übergebenen Parameter per Variable zu übergeben, hat aber nicht geklappt; da ich Generell in dem Script kaum durchblicke, weiss ich nicht, wo ich da ansetzen soll.

                    
                  $strOnet = $this->_root;  
                  $res = StringParser_Node::destroyNode ($strOnet);
                  

                  So klappt es schon mal nicht.

                  Die StringParser_Node-Funktion:

                    
                  function StringParser_Node ($occurredAt = -1) {  
                    $this->_id = $GLOBALS['__STRINGPARSER_NODE_ID']++;  
                    $this->occurredAt = $occurredAt;  
                  }  
                    
                  // Und die destroyNode-Funktion  
                  function destroyNode (&$node) {  
                    if ($node === null) {  
                      return false;  // auch hier habe ich versucht, den Rückgabewert per Variable zu übergeben, funktioniert auch nicht.  
                    }  
                  
                  

                  mfg

                  --
                  echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
                  array(2) {
                    ["SELFCODE"]=>
                    string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
                    ["Meaningful"]=>
                    string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
                  }
              2. echo $begrüßung;

                // aus dem gekürzten $_SERVER['REQUEST_URI'] möchte ich nun den letzten Wert hinter dem letzten „/“
                  define ('lastPath', array_pop (explode( '/', requestPath) ));

                Meldet mir der Parser „Strict Standards: Only variables should be passed by reference“,

                Er missbraucht hier die Array-Funktionen, um einen Teilstring zu bekommen. Das ist aber letztlich kürzer notierbar als Stringfunktionen zu verwenden. Diese geben nämlich beim Nichtvorhandensein der Suchzeichen ein false zurück, was gesondert ausgewertet werden muss und letzlich aufwendiger (zu notieren ist) als die Array-Methode ist. Der Grund für die Meldung ist jedenfalls, dass array_pop() ein Array per Referenz bekommen möchte. Referenzen gibt es aber nur auf Variablen. Vor PHP 4.4.0 war es jedoch ungestraft möglich, statt einer Referenz einen Ausdruck (Funktionsergebnis beispielsweise) zu übergeben.

                define('lastPath', implode('', array_slice(explode('/', $s), -1)));

                Das ist zwar nicht besonders schön, aber einzeilig und E_STRICT-meldungsfrei.

                Auch dieses Konstrukt kann man auf die Verwendung von Zwischenarrays statt RegExp umschreiben:

                /*
                   * $_SERVER['REQUEST_URI'], alles nach dem Fragezeichen entfernen
                   * also     „/seite/unterseite/begriff?parameter=test“
                   * soll auf „/seite/unterseite/begriff“
                   * gekürzt werden
                  */
                  define ('requestPath', preg_replace('|(.*)?(.*)+$|', "$1", $_SERVER['REQUEST_URI']));

                define('requestPath', implode('', array_slice(explode('?', $_SERVER['REQUEST_URI']), 0, 1)));

                Leider kann man den Arrayelementzugriffsoperator [$index] nur auf Variablen, nicht aber auf Ausdrücke wie Funktionsergebnisse anwenden, weswegen ich array_slice() und implode() verwende(n muss).

                echo "$verabschiedung $name";

                1. hi,

                  Danke erstmal für die zwei Beispiele, sehen wirklich nicht schön aus, Funktionieren aber Fehlerfrei.
                  Sind denn Konstanten hier richtig gewählt? Ich arbeite eher selten mit Konstanten, weiss daher nicht wirklich, wann sie angebracht sind.

                  Der Grund für die Meldung ist jedenfalls, dass array_pop() ein Array per Referenz bekommen möchte. Referenzen gibt es aber nur auf Variablen.

                  Das allerdings verstehe ich nicht so ganz; ich hatte aufgrund der Fehlermeldung das Konstrukt testweise umgeschrieben auf Variablen, sprich auf die defines verzichtet, die Meldung kam aber trotzdem, oder habe ich dich jetzt nur falsch verstanden?

                  mfg

                  --
                  echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
                  array(2) {
                    ["SELFCODE"]=>
                    string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
                    ["Meaningful"]=>
                    string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
                  }
                  1. echo $begrüßung;

                    Ich arbeite eher selten mit Konstanten, weiss daher nicht wirklich, wann sie angebracht sind.

                    Werte, die einmalig gesetzt (berechnet) werden sollen und dann unverändert zur Verfügung stehen sollen, Konfigurationsparameter beispielsweise, sind gute Kandidaten. Beispielswiese für die Zugangsdaten für ein DBMS sind Konstanten gut geeignet.

                    » Der Grund für die Meldung ist jedenfalls, dass array_pop() ein Array per Referenz bekommen möchte. Referenzen gibt es aber nur auf Variablen.
                    Das allerdings verstehe ich nicht so ganz; ich hatte aufgrund der Fehlermeldung das Konstrukt testweise umgeschrieben auf Variablen, sprich auf die defines verzichtet, die Meldung kam aber trotzdem, oder habe ich dich jetzt nur falsch verstanden?

                    Das define() macht keine Probleme. array_pop(explode()) ist das beanstandete Konstrukt. explode() liefert ein Ergebnis zurück. Seine Aufgabe ist anschließend beendet und es hält keine Referenz mehr auf das Ergebnis. array_pop() will das übergebenen Array verändern und braucht eine Referenz darauf, nicht nur dessen Daten.

                    echo "$verabschiedung $name";

                    1. hi,

                      Werte, die einmalig gesetzt (berechnet) werden sollen und dann unverändert zur Verfügung stehen sollen, Konfigurationsparameter beispielsweise, sind gute Kandidaten. Beispielswiese für die Zugangsdaten für ein DBMS sind Konstanten gut geeignet.

                      Alos in meinem Fall durchaus richtig genutzt, denke ich mal.

                      Das define() macht keine Probleme. array_pop(explode()) ist das beanstandete Konstrukt.

                      Also ist die Kombination von array_pop(explode()) einfach nicht zulässig (bzw. in PHP 5 unzulässig), Danke für den Hinweis.

                      mfg

                      --
                      echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
                      array(2) {
                        ["SELFCODE"]=>
                        string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
                        ["Meaningful"]=>
                        string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
                      }
                      1. echo $begrüßung;

                        Also ist die Kombination von array_pop(explode()) einfach nicht zulässig (bzw. in PHP 5 unzulässig), Danke für den Hinweis.

                        Seit PHP 4.4.0 wird solch ein Konstrukt zumindest angemahnt. Genauer gesagt: alle anderen Konstrukte als array_pop($variablenname) sind nicht richtig. Das gilt für alle Funtionen, die etwas per Referenz entgegennehmen, was man am vorangestellten & beim jeweiligen Parameter in der Auflistung in der Dokumentation erkennen kann.

                        echo "$verabschiedung $name";

            2. hi,

              Das lässt sich aber auch umgehen, in dem man vor der Einbindung der stringparser_bbcode.class.php E_STRICT aus dem error_reporting-Level herausnommt, und direkt danach wieder rein.

              Nachtrag für's Archiv: Man kann das error_reporting-Level erst wieder hochschrauben, nach dem man mit den BBCode-Funktionen durch ist, also das Parsen der Inhalte hinter sich gebracht hat, da auch der Aufruf der Funktionen Fehlermeldungen erzeugt.

                error_reporting(E_ALL | E_STRICT);  
                // Das Script normal abarbeiten  
                
                // Hier das error_reporting-Level runterschrauben  
                error_reporting(E_ALL);  
                require_once 'configs/stringparser_bbcode.class.php';  
                
                if ($dbcon= $_connect->query($SELECT)) {  
                  while ($row = $dbcon->fetch_assoc())  
                  {  
                    echo $bbcode->parse ($row); // Inhalte Parsen  
                  }  
                }  
                // error_reporting-Level wieder raufschrauben  
                error_reporting(E_ALL | E_STRICT);
              

              mfg

              --
              echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
              array(2) {
                ["SELFCODE"]=>
                string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
                ["Meaningful"]=>
                string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
              }
              1. Hi,

                Das lässt sich aber auch umgehen, in dem man vor der Einbindung der stringparser_bbcode.class.php E_STRICT aus dem error_reporting-Level herausnommt, und direkt danach wieder rein.

                Nachtrag für's Archiv: Man kann das error_reporting-Level erst wieder hochschrauben, nach dem man mit den BBCode-Funktionen durch ist, also das Parsen der Inhalte hinter sich gebracht hat, da auch der Aufruf der Funktionen Fehlermeldungen erzeugt.

                Echt? Also bei mir nicht, ich hab' E_STRICT vor dem Einbinden des include-Files rausgenommen, und direkt nach der Zeile wieder rein - und bekomme keine Meldungen. (Aber u.U. kommt es auf die verwendeten BBCodes an, und damit darauf, welche Methoden aufgerufen werden.)

                MfG ChrisB

                --
                Light travels faster than sound - that's why most people appear bright until you hear them speak.
            3. hi,

              Falls du mit "implementieren" irgendwas eigenes (aufwendiges) meinst, schau dir vorher die Konfigurationsdirektiven log_errors und error_log an (sind beide auch bspw. in .htaccess einstellbar).

              Das habe ich jetzt soweit über die php.ini zum laufen gekriegt (.htaccess geht nicht, weil von meinem Hoster aus die PHP-Flags nicht genutzt werden können), nur, wie kann ich jetzt Fehler, die keine PHP-Fehler in dem Sinne sind, sondern Beispielsweise Scriptseitige abbrüche, mitloggen?

              Nehmen wir an, jemand schreibt in die URI „/seite/SCRIPT-url“ oder vergleichbaren Mist, dann bricht mein Script die weitere Verarbeitung ab und gibt eine Fehlermeldung aus, nur ist das kein PHP-Fehler und wird dementsprechend auch nicht mitgeloggt, gibt es hier eine möglichkeit, auch diese Fehler mitzuloggen, quasi einen eigenen Error provozieren oder sowas in der Richutng?

              Und wie bekomme ich die URI zu der Seite, auf der der Fehler aufgetreten ist? Irgendwie bin ich heute zu Blöd zum suchen ...

              mfg

              --
              echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
              array(2) {
                ["SELFCODE"]=>
                string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
                ["Meaningful"]=>
                string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
              }
              1. Hi,

                nur, wie kann ich jetzt Fehler, die keine PHP-Fehler in dem Sinne sind, sondern Beispielsweise Scriptseitige abbrüche, mitloggen?

                Ein bisschen mehr könntest du dich im Handbuch auch mal selber umschauen - dann hättest du im Umfeld des Kapitels über Error Handling and Logging auch bspw. die Funktion error_log finden können.

                Und wie bekomme ich die URI zu der Seite, auf der der Fehler aufgetreten ist?

                print_r($_SERVER);

                MfG ChrisB

                --
                Light travels faster than sound - that's why most people appear bright until you hear them speak.
                1. hi,

                  » nur, wie kann ich jetzt Fehler, die keine PHP-Fehler in dem Sinne sind, sondern Beispielsweise Scriptseitige abbrüche, mitloggen?

                  Ein bisschen mehr könntest du dich im Handbuch auch mal selber umschauen - dann hättest du im Umfeld des Kapitels über Error Handling and Logging auch bspw. die Funktion error_log finden können.

                  Ahh, Sorry, ich dachte, error_log bezieht sich nur auf die „php.ini“ einstellungen, dass erste Beispiel ist der Schlüssel, Danke für den Hinweis.
                  Das zweite Beispiel werde ich auch gleich in Angriff nehmen.

                  » Und wie bekomme ich die URI zu der Seite, auf der der Fehler aufgetreten ist?

                  print_r($_SERVER);

                  Das dürfte jetzt kein Problem mehr darstellen. Ich wusste nur nicht, dass man die error_log nach belieben aufrufen kann. Stehe die Tage ein wenig neben mir, Sorry und Danke!

                  mfg

                  --
                  echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
                  array(2) {
                    ["SELFCODE"]=>
                    string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
                    ["Meaningful"]=>
                    string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
                  }
  2. hi,

    Danke allen helfern hier im Thread, diese Akte können wir vorerst schliessen, es sei denn, mir fällt noch ne Frage ein, die nach Stunden der Suche und Testereien zu keinem Ende kommt ;)

    Ich kam noch nicht dazu, alles zu übernehmen, da der Thread in eine unerwartete Richtung gedriftet ist (jetzt muss ich an vielen Ecken nochmal Hand anlegen); sobald ich alles zusammen getragen habe, Poste ich hier noch mal für's Archiv das wesentliche.

    mfg

    --
    echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
    array(2) {
      ["SELFCODE"]=>
      string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
      ["Meaningful"]=>
      string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
    }
    1. hi,

      es sei denn, mir fällt noch ne Frage ein, die nach Stunden der Suche und Testereien zu keinem Ende kommt ;)

      Ich hab noch ne Kleinigkeit, die mir Komplett schleierhaft ist; meine Seite wird mit UTF-8 ausgeliefert, alles ohne Probleme, nur auf dieser Seite stimmt was nicht, der letzte Eintrag bzw. Eintrag Nummer 1, da gibt es ein Charset-Problem.

      Da steht 26 M�rz 2008, alle anderen Sonderzeichen werden richtig dargestellt.

      Das Datum baut sich wie folgt zusammen:

        ini_set('date.timezone','Europe/Berlin');  
        setlocale(LC_ALL, 'de_DE');  
        
       $Date = strftime("%A, %d %B %Y", strtotime($news_row['date']));
      

      Hat die PHP-Eigene Funktion Eventuell Probleme mit dem Deutschen Datumsformat? Anders könnte ich es mir nicht erklären.

      Es scheint wohl Tatsächlich mit der Funktion zusammenzuhängen, habe gerade einen Test auf der Startseite druchgeführt, gleiches Resultat; lässt sich das beheben?

      mfg

      --
      echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
      array(2) {
        ["SELFCODE"]=>
        string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
        ["Meaningful"]=>
        string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
      }
      1. echo $begrüßung;

        Da steht 26 M�rz 2008, alle anderen Sonderzeichen werden richtig dargestellt.
          setlocale(LC_ALL, 'de_DE');
        Hat die PHP-Eigene Funktion Eventuell Probleme mit dem Deutschen Datumsformat?

        Nein, sie liefert nur das was dein System per Default bei de_DE ausliefert und das wird Latin1 sein. Welche Locale-Einstellungen es gibt, kannst du mit locale -a in der Shell auflisten oder mit einem Systemaufruf. PHP hat da keine Funktion, soweit ich das sehe. Ob in der Liste eine mit UTF-8-Zusatz steht ... wenn nicht, bleibt ja immer noch ein utf8_encode() als Möglichkeit. In die Richtung UTF-8 gibt es ja keinen Datenverlust.

        echo "$verabschiedung $name";

        1. hi,

          Nein, sie liefert nur das was dein System per Default bei de_DE ausliefert und das wird Latin1 sein. Welche Locale-Einstellungen es gibt, kannst du mit locale -a in der Shell auflisten oder mit einem Systemaufruf. PHP hat da keine Funktion, soweit ich das sehe. Ob in der Liste eine mit UTF-8-Zusatz steht ... wenn nicht, bleibt ja immer noch ein utf8_encode() als Möglichkeit. In die Richtung UTF-8 gibt es ja keinen Datenverlust.

          Am System will ich mal lieber nicht rumpfuschen, zumal auch bei meinem Hoster das gleiche Problem besteht, wie Lokal, daher wird mir das nicht viel bringen.
          Mit utf8_encode() funktioert es, kam da Gestern nicht mehr auf die Idee, Danke.

          mfg

          --
          echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
          array(2) {
            ["SELFCODE"]=>
            string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
            ["Meaningful"]=>
            string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
          }
          1. echo $begrüßung;

            » Nein, sie liefert nur das was dein System per Default bei de_DE ausliefert und das wird Latin1 sein. Welche Locale-Einstellungen es gibt, kannst du mit locale -a in der Shell auflisten oder mit einem Systemaufruf.
            Am System will ich mal lieber nicht rumpfuschen, zumal auch bei meinem Hoster das gleiche Problem besteht, wie Lokal, daher wird mir das nicht viel bringen.

            Du solltest auch nur nachsehen, welche installiert sind und wie die genau heißen. Dann kannst du mit den normalen PHP-setlocale() diesen erspähten Namen angeben.

            echo "$verabschiedung $name";

            1. hi,

              Du solltest auch nur nachsehen, welche installiert sind und wie die genau heißen. Dann kannst du mit den normalen PHP-setlocale() diesen erspähten Namen angeben.

              Lokal werde ich es heute Abend, wenn ich wieder an meinem Rechner sitze, probieren, dass rauszufinden (Windows XP, auf Wikipeadia habe ich schon was gefunden, muss es mal testen). Aber wie könnte ich es bei meinem Hoster rausfinden? Eventuell anschreiben?

              mfg

              --
              echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
              array(2) {
                ["SELFCODE"]=>
                string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
                ["Meaningful"]=>
                string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
              }
              1. echo $begrüßung;

                Aber wie könnte ich es [vorhandene locale-Settings] bei meinem Hoster rausfinden? Eventuell anschreiben?

                Wäre eine Möglichkeit. Eine andere wäre, mit system('locale -a') oder system('/usr/bin/locale -a') den Aufwand auf ein Minimum zu reduzieren und das Ergebnis sofort zu haben. Auch die PHP Shell kann helfen. Wenn du allerdings (so wie ich) nur C und POSIX rausbekommst, bin ich überfragt, wo sich da das anscheinend funktionierende de_DE versteckt.

                echo "$verabschiedung $name";

                1. hi,

                  Wäre eine Möglichkeit. Eine andere wäre, mit system('locale -a') oder system('/usr/bin/locale -a') den Aufwand auf ein Minimum zu reduzieren und das Ergebnis sofort zu haben. Auch die PHP Shell kann helfen. Wenn du allerdings (so wie ich) nur C und POSIX rausbekommst, bin ich überfragt, wo sich da das anscheinend funktionierende de_DE versteckt.

                  ;)

                  C
                  POSIX

                  Ich muss dazu sagen, dass Lokal bei mir de_DE nicht funktioniert, Lokal steht bei mir setlocale(LC_ALL, 'de_DE','deu_deu');.

                  Ich werde mal den Support anschreiben und dort fragen.
                  Nur, wonach frage ich bzw. was suche ich? Eventuell steht ja schon was in den FAQ dazu.

                  mfg

                  --
                  echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
                  array(2) {
                    ["SELFCODE"]=>
                    string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
                    ["Meaningful"]=>
                    string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
                  }
      2. Hello,

        da gibt es ein Charset-Problem.

        Da steht 26 M�rz 2008, alle anderen Sonderzeichen werden richtig dargestellt.

        Mittwoch, 26 M�rz 2008

        sieht aus, wie doppelt codiert.

        Liebe Grüße aus dem schönen Oberharz

        Tom vom Berg

        --
        Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
  3. hi,

    bevor der Thread ins Archiv wandert noch ne Kleinigkeit ;)

    Ich habe das Sessionbasierte Loginsystem von Benjamin erweitert und in eine Funktion gesteckt, dabei kam mir der gedanke, dass die SESSION-Variable „$_SESSION['angemeldet']“ einfach nur auf True gesetzt wird; jetzt wird aber häufig in Diskussionen erwähnt, dass man doch der Session einen eindeutigen Wert zuweisen sollte, der dann möglichst per Zufall generiert werden sollte; ist dieses Script denn in seiner jetzigen Form Sicher?

    Es geht nur um einen Admin-bereich, wo nur ich mich anmelden kann, aber wenn ich schon dabei bin, möchte ich es auch gleich Vernünftig machen.

    Die Funktion sieht wie folgt aus:

      function LoggedIn ($_connect)  
      {  
        if ($_Log = $_connect->query("SELECT username, passwort FROM cms_admin"))  
          while ($_Row = $_Log->fetch_assoc())  
            if ($_SERVER['REQUEST_METHOD'] == 'POST')  
            {  
              if (isset($_POST['username']) AND ($_POST['username'] ==$_Row['username'])  
              AND isset($_POST['passwort']) AND (md5($_POST['passwort']) == $_Row['passwort']))  
              {  
                $_SESSION['angemeldet'] = true;  
              }  
              else if (isset($_POST['abmelden']))  
              {  
                session_destroy();  
                header('Location: http://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']));  
              }  
            }  
      
        if (isset($_SESSION['angemeldet']))  
          return true;  
        else  
          return false;  
      }
    

    mfg

    --
    echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
    array(2) {
      ["SELFCODE"]=>
      string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
      ["Meaningful"]=>
      string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
    }
    1. echo $begrüßung;

      Ich habe das Sessionbasierte Loginsystem von Benjamin erweitert und in eine Funktion gesteckt, dabei kam mir der gedanke, dass die SESSION-Variable „$_SESSION['angemeldet']“ einfach nur auf True gesetzt wird; jetzt wird aber häufig in Diskussionen erwähnt, dass man doch der Session einen eindeutigen Wert zuweisen sollte, der dann möglichst per Zufall generiert werden sollte; ist dieses Script denn in seiner jetzigen Form Sicher?

      Sicher wovor genau? Die Session hat doch schon eine Session-ID, was ein zufälliger Wert ist. Vielleicht willst du CSRF verhindern?

      echo "$verabschiedung $name";

      1. hi,

        Sicher wovor genau? Die Session hat doch schon eine Session-ID, was ein zufälliger Wert ist.

        Ah Sorry, ich habe den Session-Mechanismus mit Cookies verwechselt; bei den Diskussionen, auf die ich angespielt hatte, geht es Primär um langzeit-Logins, wo der User anhand eines Cookies wieder erkannt werden soll, was aber bei mir ja gar nicht der Fall ist.

        Vielleicht willst du CSRF verhindern?

        Das kannte ich noch nicht, Danke für den Link.

        mfg

        --
        echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
        array(2) {
          ["SELFCODE"]=>
          string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
          ["Meaningful"]=>
          string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
        }