kostenloser Webspace werbefrei: lima-city


Problem OOP

lima-cityForumProgrammiersprachenPHP, MySQL & .htaccess

  1. Autor dieses Themas

    progger

    Kostenloser Webspace von progger

    progger hat kostenlosen Webspace.

    Hallo,
    ich habe wieder mal ein Problem, undzwar:
    folgendes PHP-Skript soll einen User erstellen, dessen Werte man jederzeit einlesen und überschreiben kann.
    Das Problem dabei ist nur, dass nie ein Wert im Array der geänderten Werte landet.
    //user.php
    <?php
    class USER{
    
      private $changed = array();
      private $ready = false;
    
      function __construct($id){
        $a = mysql_query('SELECT * FROM user WHERE id = "'.$id.'"');
        $b = mysql_fetch_assoc($a);
        foreach($b as $key => $value){
          $this->$key = $value;
        }
        $this->ready = true;
      }
      
      function __set($name,$value){
        if($this->ready){
          $this->changed[$name] = $value;
        }
        $this->$name = $value;
      }
      
      function __destruct(){
        if($this->changed){
          foreach($this->changed as $x => $y){
            $z[] = mysql_escape_string($x).' = "'.mysql_escape_string($y).'"';
          }
          $sql = 'UPDATE user SET '.implode(',',$z).' WHERE id = '.$this->id.'';
          mysql_query($sql);
        }
      }
    }
    ?>


    Beitrag zuletzt geändert: 31.7.2009 9:52:52 von progger
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. Ich blicke durch deinen Code nicht ganz durch, die Nutzung der MM __set ist etwas seltsam:
    function __set($name,$value){
        if($this->ready){
          $this->changed[$name] = $value;
        }
        $this->$name = $value;
      }


    Beim Aufrufen des Konstruktors ist es noch nicht ready. Also wird nur zweiteres ausgeführt:
    $this->$name = $value;

    Wenn du eine Eigenschaft $name hättest und ich gehe einfach mal davon aus, dass du sie nicht hast (hast ja nur ready und changed), würde in diese geschrieben werden. So müsste aber eigentlich wieder __set aufgerufen werden. Also abbruchlose Rekursion. Scheinbar wird es aber nicht so ausgeführt, sonst müsste er dir einen Fehler werfen...

  4. Autor dieses Themas

    progger

    Kostenloser Webspace von progger

    progger hat kostenlosen Webspace.

    Stimmt,
    es wirft keinen Fehler;
    das Problem liegt darin, dass $ready immer false ist, obwohl es im Konstruktor auf true gesetzt wird.
    Und das $ready hat auch seine Existenzberechtigung, da ich ja die geänderten Werte im Array haben will.
    Ohne die Schleife wäre jede Eigenschaft des Objekts im Array, weil ja alle Werte im Konstruktor gesetzt werden.
    Übrigens ist
    $name = "x";
    $this->$name = "x";

    dasselbe wie:
    $this->x = "x";


    Beitrag zuletzt geändert: 30.7.2009 15:08:45 von progger
  5. Schon klar, das beschriebenes Phänomen gilt. Aber du hast ja keine Eigenschaft 'x' definiert. Und wenn keine definiert ist, dann wird __set('x', $value); aufgerufen. Und da es da thix->x immernoch nicht gibt, wird wieder __set('x', $value); aufgerufen. Und so geht das immer weiter. Es bricht nie ab. Daher kommt PHP gar nicht erst dazu den User ready zu machen...

    Try out this:
    //user.php
    <?php
    class USER{
    
      private $changed = array();
    private $old = array();
      private $ready = false;
    
      function __construct($id){
        $a = mysql_query('SELECT * FROM user WHERE id = "'.$id.'"');
        $b = mysql_fetch_assoc($a);
        foreach($b as $key => $value){
          $this->$key = $value;
        }
        $this->ready = true;
      }
      
      function __set($name,$value){
        if($this->ready){
          $this->changed[$name] = $value;
        }
    else {
        $this->old[$name] = $value;
    }
      }
      
      function __destruct(){
        if($this->changed){
          foreach($this->changed as $x => $y){
            $keys[] = mysql_escape_string($x);
            $values[] = '"'.mysql_escape_string($y).'"';
          }
          $sql = 'UPDATE user ('.implode(',',$keys).') VALUES ('.implode(',',$values).')';
          mysql_query($sql);
        }
      }
    }
    ?>

    Nicht getestet, wie immer.
    Aber überhaupt halte ich das ganze, was du da machst für wenig sinnvoll...
  6. Autor dieses Themas

    progger

    Kostenloser Webspace von progger

    progger hat kostenlosen Webspace.

    Es ist sinnvol, da es mir eine Menge Datenbank-Anfragen spart.
    Außerdem lassen sich alle Werte aus dem Objekt auslesen, nur speichern lässt sich nichts.
  7. Ist das der ganze Code?
  8. Autor dieses Themas

    progger

    Kostenloser Webspace von progger

    progger hat kostenlosen Webspace.

    Ja, das ist alles, und meiner Meinung nach ist jede Zeile richtig :confused:
  9. das Problem liegt darin, dass $ready immer false ist, obwohl es im Konstruktor auf true gesetzt wird.
    das trifft nicht zu.
    Das Problem dabei ist nur, dass nie ein Wert im Array der geänderten Werte landet.
    auch das trifft nicht zu.
    um die aussagen zu veranschaulichen hir ein testlauf: http://czibere.lima-city.de/progger/user_class.php (natürlich etwas abgeändert daher mit source).

    folgendes PHP-Skript soll einen User erstellen, dessen Werte man jederzeit einlesen und überschreiben kann.
    seltsam anmutendes bei der aussage:
    - wenn du einen user erstellen willst, warum wird aus der db gleich nach id's gelesen? (woher weißt du die id eines noch nicht existierenden users?)
    - welche daten genau landen in dem object und vor allem warum?

    ob das was du vorhast jetzt 'wenig sinvoll' ist oder nicht, sei dahingestellt, aber auf alle fälle ist das verwirrend. ich kann die vermutung nicht unterdrücken, dass du zwei funktionen auf einmal von nur einer funktion erwartest.

    meiner Meinung nach ist jede Zeile richtig
    gold richtig, aber: bis auf die kleinigkeit, dass ich das ganze nicht ganz überzukkere; das was du von dem object erwartest, ist laut testlauf erfüllt! korrigiere mich bitte ...
  10. Autor dieses Themas

    progger

    Kostenloser Webspace von progger

    progger hat kostenlosen Webspace.

    czibere schrieb:
    das Problem liegt darin, dass $ready immer false ist, obwohl es im Konstruktor auf true gesetzt wird.
    das trifft nicht zu.
    Das Problem dabei ist nur, dass nie ein Wert im Array der geänderten Werte landet.
    auch das trifft nicht zu. um die aussagen zu veranschaulichen hir ein testlauf: http://czibere.lima-city.de/progger/user_class.php (natürlich etwas abgeändert daher mit source).

    Ich habe meine Klasse ausreichend getestet und ich bin zu den von mir beschriebenen Problemen gekommen.
    Was deine Klasse angeht: die finde ich verwirrend :wink:

    seltsam anmutendes bei der aussage:
    - wenn du einen user erstellen willst, warum wird aus der db gleich nach id's gelesen? (woher weißt du die id eines noch nicht existierenden users?)
    - welche daten genau landen in dem object und vor allem warum?

    1.: die ID nehme ich einfach aus der Session:
    $_USER = new USER($_SESSION['ID']);

    2.: Jeder Wert der in der Datenbank zum User steht, ist auch im Objekt ansprechbar.
    Ich will mir im Prinzip nur überflüssige Querys ersparen (mal ehrlich: das escapen und fetchen nervt schon etwas :wink:)

    Beitrag zuletzt geändert: 31.7.2009 10:04:25 von progger
  11. oops! ich wollte dir nicht zu nah treten ... ich habe nur schwierigkeiten gehabt, um deine zielformulierung über deine klasse zu verstehen.
  12. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!