Daten eines Objekts anzeigen

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Daten eines Objekts anzeigen

    Hallo, habe bisher folgenden Output(Werte gekürzt):

    PHP-Code:
    Message Object ( [Headline] => [Body] => [Images] => [Editable] => [Owner] => [Creation] => [Category] => [Issue] => [Headline:protected] => Elemente neu... [Body:protected] => Es ist nicht sodaß... [Images:protected] => [Editable:protected] => [Owner:protected] => M_S-2000-04 [Creation:protected] => 1429969983 [Category:protected] => Chemie [Issue:protected] => Durchführungsart 030 
    Nun will ich aber nur die eigentlichen Werte wie
    Elemente neu..., Es ist nicht so, daß..., 3, M_S-2000-04, 1429969983, Chemie, Durchführungsart 030
    anzeigen lassen, also all das was im Objekt protected ist.
    Brauche ich dazu Magic Methods wie einen sog. getter? Wenn ja, wie ginge das?

    MONI
    Zuletzt geändert von rernanded; 27.04.2015, 01:08.

  • #2
    public function getter( $field ){ return $this->$field; }

    Aber dann ist es absurd deine Variablen protected zu machen, dann kannst du die auch public verwenden, ausser, du möchtest natürlich den direkten Schreibzugriff verhindern.

    Kommentar


    • #3
      Zitat von chorn Beitrag anzeigen
      public function getter( $field ){ return $this->$field; }

      Aber dann ist es absurd deine Variablen protected zu machen, dann kannst du die auch public verwenden, ausser, du möchtest natürlich den direkten Schreibzugriff verhindern.
      Hallo.

      Daten kommen alle aus einem Blob das data heisst. Wie serialisiert wurde weiß ich nicht. Nun muß ich die gespeicherten Werte anzeigen lassen um zu wissen was drin ist.
      Benutze dazu folgenden Code (unten). Die view.class habe ich auch beigefügt (noch weiter unten) Aber ich krieg alles nicht zum Laufen.
      Ich benutze auch noch kein mysqli aber das ist glaub ich nicht so wichtig.

      MONI

      PHP-Code:

            
      include_once("view-connection.php");

            
      $sql "SELECT * FROM FD_Articles ORDER BY id DESC";

            
      $ergebnis =    mysql_query($sql) or die("SQL Error: ".mysql_error());

            
      $anz_ds =    mysql_num_rows($ergebnis);

            for (
      $ii $ii $anz_ds $ii++) {
            
      $id mysql_result($ergebnis,$ii,"id");

            
      $data mysql_result($ergebnis,$ii,"data");

            
      //var_dump($data);
            //var_dump(unserialize($data));

      require_once("view.class.php");

      echo 
      "<br />";

      $message unserialize($data);

      print_r($message);


      PHP-Code:

      class Message {

        
      /**
        * Überschrift
        * @var string
        */
        
      public $Headline;
       
        
      /**
        * Körper
        * @var string
        */
        
      public $Body;
         
        
      /**
        * Bilddaten
        * @var array
        */
        
      public $Images;
         
        
      /**
        * Editierbar
        * @var boolean
        */
        
      public $Editable;
         
        
      /**
        * Eigentümer
        * @var string
        */
        
      public $Owner;
         
        
      /**
        * Zeitpunkt der Erstellung als Unixtimestamp
        * @var int
        */
        
      public $Creation;
         
        
      /**
        * Kategorie
        * @var string
        */
        
      public $Category;
         
        
      /**
        * Sonstiges
        * @var string
        */
        
      public $Issue;


      Zuletzt geändert von rernanded; 28.04.2015, 14:39.

      Kommentar


      • #4
        Zitat von rernanded Beitrag anzeigen
        Nun will ich aber nur die eigentlichen Werte ... Chemie, Durchführungsart 030
        anzeigen lassen, also all das was im Objekt protected ist.
        Brauche ich dazu Magic Methods wie einen sog. getter? Wenn ja, wie ginge das?
        Wenn du die Klasse selbst erstellst, geht das so:

        PHP-Code:
        class Whatever {
            function 
        __get($property) {
                return 
        $this->$property;
            }

        Wahlweise könntest du auch ein ArrayAccess-Interface implementieren.

        Bei einem Objekt, an dessen Bauplan (Klasse) du nicht herumfummeln darfst, kommst du nur über Reflection oder Type-Casting zu einem Array an die geschützten Membervariablen.

        PHP-Code:
        var_dump((array) $my_opaque_object); 
        Letzteres erzeugt allerdings "rohe" Keys. Die bekommt man wieder weg, indem man das Array in Keys und Values zerlegt, die Keys "repariert" und beides wieder zusammenklebt:

        PHP-Code:
        $unmangled array_combine(
            
        // keys (property names)
            
        array_map(
                function (
        $item) {
                    
        // remove "private" and "protected" markers
                    
        return preg_replace('/\A\x0.+?\x0/'''$item);
                },
                
        array_keys((array) $my_opaque_object)
            ),
            
        // values
            
        (array) $my_opaque_object
        ); 
        Das klappt zwar, sieht aber unschön aus. Weiterhin wird diese Vorgehensweise von offizieller Seite missbilligt, weil sie nicht mehr funktionieren würde, wenn sich die Objekt-Interna in zukünftigen PHP-Versionen ändern würden.

        Der offizielle Weg geht daher über ein ReflectionObject. PHP's Reflection ist allerdings etwas umständlich zu bedienen. Am besten schreibst dir daher ein Wrapper-Objekt, das die Arbeit macht. Etwa so:

        PHP-Code:
        class Introspector {
            protected 
        $obj;
            protected 
        $rfl;

            function 
        __construct($obj) {
                if (!
        is_object($obj)) {
                    throw new 
        Exception();
                }
                
        $this->obj $obj;
                
        $this->rfl = new ReflectionObject($obj);
            }

            
        // todo: show member variables of parent classes

            
        function __get($name) {
                
        $prop $this->rfl->getProperty($name);
                if (!
        $prop->isPublic()) {
                    
        $prop->setAccessible(true);
                }
                return 
        $prop->getValue($this->obj);
            }

            
        // if someone wants foreach loops
            
        function traverse() {
                foreach (
        $this->rfl->getProperties() as $prop) {
                    if (!
        $prop->isPublic()) {
                        
        $prop->setAccessible(true);
                    }
                    yield 
        $prop->getName() => $prop->getValue($this->obj);
                }
            }

            
        // a minimalistic (Python like) dictionary interface

            
        function has($key) {
                return 
        $this->rfl->hasProperty($key);
            }

            function 
        get($key$default null) {
                if (!
        $this->rfl->hasProperty($key) && func_num_args() > 1) {
                    return 
        $default;
                }
                return 
        $this->__get($key);
            }

        Anwendung:
        PHP-Code:
        $intr = new Introspector($test);

        // test the Generator::|Iterator:: interface
        foreach ($intr->traverse() as $name => $value) {
            
        var_dump($name);
            
        var_dump($value);
        }

        // test get() with default return value
        // should return null
        var_dump($intr->get('unknown'null));

        // test get() with exception
        // should throw an exception
        var_dump($intr->get('unknown')); 
        Zuletzt geändert von fireweasel; 07.05.2015, 00:35. Grund: änderung in der klassendeklaration
        Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

        Kommentar


        • #5
          Die Eigenschaften sind doch eh public. Wo ist das Problem?

          Kommentar


          • #6
            Zitat von h3ll Beitrag anzeigen
            Die Eigenschaften sind doch eh public.
            Anscheinend nicht. So, wie ich das verstehe, hat die Klasse "Message" nichts mit dem deserialisierten Objekt zu tun.

            Zitat von rernanded Beitrag anzeigen
            Daten kommen alle aus einem Blob das data heisst. Wie serialisiert wurde weiß ich nicht. Nun muß ich die gespeicherten Werte anzeigen lassen um zu wissen was drin ist.
            Wo ist das Problem?
            Der (erste) Quellcode-Ausschnitt in http:///forum/php-developer-forum/10...tml#post670872 ist doch für sich schon problematisch genug ...
            Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

            Kommentar


            • #7
              Für mich sieht das aus, als wär da irgendwas kaputt. Ich würde nicht nachträglich daran herumfummeln, sondern die Ursache für das Problem beheben. Warum hat das serialisierte Objekt protected Eigenschaften, die in der ursprünglichen Klasse gar nicht vorkommen?
              Zuletzt geändert von h3ll; 07.05.2015, 12:01.

              Kommentar


              • #8
                Zitat von h3ll Beitrag anzeigen
                Für mich sieht das aus, als wär da irgendwas kaputt. Ich würde nicht nachträglich daran herumfummeln, sondern die Ursache für das Problem beheben. Warum hat das serialisierte Objekt protected Eigenschaften, die in der ursprünglichen Klasse gar nicht vorkommen?
                Die Klassendeklaration ist das, was der Threaderöffner gerne hätte. Der serialisierte Datenblob ist das, was er vor sich hat. So hab ich ihn jedenfalls verstanden. Für Aufklärung kann nur er (oder sie) selbst sorgen.
                Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

                Kommentar


                • #9
                  Warum dann nicht die ursprüngliche Klasse vor dem Serialisieren anpassen?

                  Kommentar


                  • #10
                    Zitat von h3ll Beitrag anzeigen
                    Warum dann nicht die ursprüngliche Klasse vor dem Serialisieren anpassen?
                    Wie willst du das machen, wenn du von irgendwoher eine Datenquelle (Datenbank-Tabelle, Datei, was-auch-immer) vorgesetzt bekommst, aus der du lediglich die serialisierte Form (einen String mit Bytes drin) herausfischen kannst?

                    Wenn der Threaderöffner ein PHP-Script vorliegen hätte, das die entsprechenden Datensätze baut und Objekte dahinein serialisiert, würde sich das Problem doch erst gar nicht stellen, oder?
                    Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

                    Kommentar


                    • #11
                      Zitat von fireweasel Beitrag anzeigen
                      Wie willst du das machen, wenn du von irgendwoher eine Datenquelle (Datenbank-Tabelle, Datei, was-auch-immer) vorgesetzt bekommst, aus der du lediglich die serialisierte Form (einen String mit Bytes drin) herausfischen kannst?
                      Einmalig konvertieren. Denn hoffentlich ist sowas kein Dauerzustand, dass eine Anwendung in der Datenbank einer anderen Anwendung herumpfuscht.

                      Kommentar


                      • #12
                        ..., dass eine Anwendung in der Datenbank einer anderen Anwendung herumpfuscht.
                        Naja, es werden ja nur Datensätze ausgelesen, nicht verändert (hoffentlich). Trauriger finde ich, dass strukturierte Daten als serialisierter Blob abgelegt werden, den man nur per PHP auswerten kann, anstatt SQL damit zu behelligen.

                        Denn hoffentlich ist sowas kein Dauerzustand, ...
                        Du Optimist!
                        Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

                        Kommentar

                        Lädt...
                        X