kostenloser Webspace werbefrei: lima-city


Classeninstanz 'updaten'

lima-cityForumProgrammiersprachenPHP, MySQL & .htaccess

  1. Autor dieses Themas

    programtools

    programtools hat kostenlosen Webspace.

    Hi,

    ich habe ein kleines OOP-Problem:

    nehmen wir an die Klasse Benutzer repräsentiert einen Benutzer. Die Klasse Mitglied erweitert die Klasse Benutzer um einige Funktionen speziell für Mitglieder.

    Jetzt habe ich für einen Benutzer eine Instanz der Klasse Benutzer. Dieser Benutzer wird nun als Mitglied aufgenommen. Jetzt müsste ich den Benutzer um die Funktionen der Mitgliedklasse erweitern.

    Natürlich könnte ich einfach eine neue Instanz auf die Klasse Mitglied anlegen und die Instanz auf die Klasse Benutzer löschen. Aber die ganzen Grunddaten sind ja bereits geladen (Da Mitglied Benutzer nur erweitert, enthält es ja die Grundstruktur, und somit auch den Teil, in dem alle Daten von der DB geladen werden).

    Mir erscheint es daher sinnlos, die ganzen Daten erneut zu laden obwohl sie doch eigentlich bereits da sind. Gibt es, um dies eleganter zu lösen, eine Art Update-Funktion?

    Ich möchte also meine Instanz der Klasse Benutzer zu einer Instanz der Klasse Mitglied (welche Klasse ja die Klasse Benutzer erweitert) 'updaten'.

    Wäre cool wenn jemand damit erfahrung hat oder auch schonmal vor dem 'Problem' stand. Vielleicht gibt es auch ne ganz andere Lösung?

    Vielen Dank & Grüße
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

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

  3. Hallo
    Wie darf man das 'erweitert' verstehen?
    Wenn die Klasse Benutzer von der Klasse Mitglied erbt, erhälst du ja automatisch alle Methoden der Klasse Mitglied, wenn dies ist was du willst. Dann würdest du durch die Vererbung, wenn du eine Instanz der Klasse Benutzer erstellst auch die Methoden von der Klasse Mitglied erhalten...
  4. Autor dieses Themas

    programtools

    programtools hat kostenlosen Webspace.

    sjay96 schrieb:
    Hallo
    Wie darf man das 'erweitert' verstehen?
    Wenn die Klasse Benutzer von der Klasse Mitglied erbt, erhälst du ja automatisch alle Methoden der Klasse Mitglied, wenn dies ist was du willst. Dann würdest du durch die Vererbung, wenn du eine Instanz der Klasse Benutzer erstellst auch die Methoden von der Klasse Mitglied erhalten...


    Es ist genau anderst herum.

    Mitglied erbt von Benutzer.

    Beispiel des Problems:
    <?php
      $Benutzer = new Benutzer();
    
     //*Code der den Benutzer nun zu einem Mitglied macht, weil der benutzer sich zB. jetzt den Button 'mitglied sein' gedrückt hat und deshalb nun als Mitglied markiert ist *//
    
      $Benutzer = new Mitglied(); //würde die Daten des Benutzers neu laden, obwol diese ja schon in $Benutzer vorhanden sind.
    
    //deswegen wäre eine Lösung gut, $Benutzer von Class::Benutzer zu Class::Mitglied zu 'updaten' 
    //Damit nicht der Constructor der Klasse Benutzer erneut durchläuft (weil der Constructor der Klasse Benutzer ist ja auch in //der Klasse Mitglieder enthalten, da diese von Benutzer erbt
    
    
    ?>


    Es geht mir also darum, dass die Daten die in der Klasseninstanz von Benutzer ja bereits geladen wurden nicht erneut geladen werden müssen, sondern nur das neu zur Instanz kommt, um was die Klasse Benutzer von der Klasse Mitglied erweitert wurde.

    Vieled Dank & Grüße
  5. Hi,

    ehrlich gesagt sollte der Fall, so wie du ihn beschreibst, gar nicht unbedingt auftreten, deswegen ist das Problem auch eher abstrakt. Eine normale Lösung sähe etwa so aus, ich denke zwar nicht, dass es das ist was du haben willst, aber es ist eine übliche Praxis:
    Benutzer.php
    <?php
    class Benutzer
    {
      protected $name;
      protected $age;
    
      public function __construct($config = array())
      {
        $this->configure($config);
      }
    
      public function configure($config = array())
      {
        if(is_array($config)){
          $this->configureByArray($config);
        }else if($config instanceof Benutzer){
          $this->configureByObject($config);
        }
      }
    
      protected function configureByArray(array $config)
      {
        $attributes = array_keys(get_class_vars(__CLASS__));
        foreach($attributes as $key){
          if(isset($config[$key])){
            $this->{$key} = $config[$key];
          }
        }
      }
    
      protected function configureByObject(Benutzer $config)
      {
        $attributes = array_keys(get_class_vars(__CLASS__));
        foreach($attributes as $key){
          $this->{$key} = $config->{$key};
        }
      }
    
      public function __get($key)
      {
        if(property_exists($this, $key)){
          return $this->{$key};
        }
      }
    }

    Mitglied.php
    <?php
    require_once 'Benutzer.php';
    
    class Mitglied extends Benutzer
    {
      protected $clubnumber;
    
      public function configure($config = array())
      {
        parent::configure($config);
        if(is_array($config)){
          $this->clubnumber = $config['clubnumber'];
        }elseif($config instanceof Mitglied){
          $this->clubnumber = $config->clubnumber;
        }
      }
    }


    testscript.php
    <?php
    require_once 'Mitglied.php';
    
    $benutzer = new Benutzer(array('name' => 'Foo', 'age' => 20));
    $mitglied = new Mitglied($benutzer);
    $mitglied->configure(array('clubnumber' => 1));
    unset($benutzer);
    
    // Testausgaben
    echo 'Name: ' . $mitglied->name . PHP_EOL;
    echo 'Age: ' . $mitglied->age . PHP_EOL;
    echo 'Clubnumber: ' . $mitglied->clubnumber . PHP_EOL;

    Ich denke, dass sollte deine Probleme beheben, auch wenn ich nicht genau weiß, wie du in diese komische Situation geraten bist, denn die Situation die du beschreibst tritt zwischen 2 Aufrufen auf und sollte dadurch in PHP eher selten passieren.

    Mit freundlichen Grüßen
  6. Nemoinho hat es eigentlich sehr gut auf den Punkt gebracht. Mir ist noch eine weitere Methode eingefallen, die ich allerdings nicht empfehlen würde. Einerseits zu fehleranfällig und anderseits denke ich, dass sie langsamer ist, als das von nemoinho beschriebene Vorgehen.

    Nichts desto trotz wollte ich sie einfach mal als Alternatividee los werden:
    Voraussetzung Mitglied hat mindestens die gleichen Variablen und Funktionen wie Benutzer, was durch die Vererbung ja gegeben ist. Und Benutzer hat keine Variablennamen, -inhalte oder Funktionsnamen mit "Benutzer".
    $klasseBenutzer = '\Benutzer';
    $klasseBenutzerOhneBackslash = 'Benutzer';
    $klasseMitglied = '\Mitglied';
    $klasseMitgliedOhneBackslash = 'Mitglied';
    
    $benutzer = new $klasseBenutzer;
    var_dump($benutzer);
    
    $serializeBenutzer = serialize($benutzer);
    var_dump($serializeBenutzer );
    
    $one = 1; // fuck off pass by reference...
    $serializeMitglied = str_replace($klasseBenutzerOhneBackslash, $klasseMitgliedOhneBackslash, $serializeBenutzer, $one);
    var_dump($serializeMitglied);
    
    $serializeMitglied = str_replace('O:'.strlen($klasseBenutzerOhneBackslash), 'O:'.strlen($klasseMitgliedOhneBackslash), $serializeMitglied, $one);
    var_dump($serializeMitglied);
    
    $mitglied = unserialize($serializeMitglied);
    var_dump($mitglied);


    Ist allerdings nicht ausführlich getestet und nur als theoretische Idee aufzufassen. :)
  7. Ganz ehrlich, du solltest nochmal über dein Klassen Modell nachdenken. Klassen Vererbung ist zwar schön und gut, aber man sollte sie auch richtig einsetzen. Grundsätzlich sollte eine Benutzer Klasse zum Beispiel, alle möglichen Felder haben die von der Application vorgesehen sind.

    Ob diese nun benutzt werden oder nicht, ist völlig egal, es macht von der Performance absolut keinen Unterschied. Wenn dann nur minimal und das ist in 99,99999% der Fälle auch völlig egal. Erst wenn die Application massiv benutzt wird, 1 Mio. anfragen die Minute, dann kann man sich über solche Optimierungen Gedanken machen.

    Außerdem sollten Klassen, wie eine Benutzer-Klasse, beschreibend sein und nur Methoden für die Manipulationund Erstellung bereitstellen. Alles andere sollte von dedizierten Klassen und Funktionen ver-/be-/abge-arbeitet werden.


    In deinem Fall würde ich einfach ein zusätzliches Feld hinzufügen, dass die Berechtigung des Benutzers beschreibt. Kein Hickhack mit unterschiedlichen/vererbten Klassen.
  8. 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!