Encoder: Syntaxfrage

Hallo @all
Ich spiel grad mit einem XML-Parser rum (nebensächlich) und hab folgenden Beispielcode

$attributes = $xmlObject->xmlElement[0]->attributes();
echo $attributes["Name"];

Kann man daraus etwas einzeiliges machen, in der Art $xmlObject->xmlElement[0]->attributes()["Name"]; ? Habs nämlich bisher nicht geschafft.

  1. Hallo,

    $attributes = $xmlObject->xmlElement[0]->attributes();
    echo $attributes["Name"];
    Kann man daraus etwas einzeiliges machen, in der Art $xmlObject->xmlElement[0]->attributes()["Name"]; ? Habs nämlich bisher nicht geschafft.

    nein, in PHP nicht. PHP ist nicht in der Lage, ein Array "freihändig" weiterzuverarbeiten, das nicht als Variableninhalt vorliegt. Das habe ich auch schon hier und da bedauert, etwa wenn man getimagesize() aufruft, aber nur einen einzigen Wert aus dem Ergebnis-Array braucht.
    Manche anderen Sprachen wie z.B. Javascript können das.

    Ciao,
     Martin

    --
    Die letzten Worte des Polizisten:
    Ich hab mitgezählt, Leute: Sechs Schuss, jetzt hat er keine Munition mehr!
    Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
  2. Hello,

    Ich spiel grad mit einem XML-Parser rum (nebensächlich) und hab folgenden Beispielcode

    $attributes = $xmlObject->xmlElement[0]->attributes();
    echo $attributes["Name"];

    Kann man daraus etwas einzeiliges machen, in der Art $xmlObject->xmlElement[0]->attributes()["Name"]; ? Habs nämlich bisher nicht geschafft.

    Dazu müsstest Du die Methode (eigentlich scheint es ja sowieso eine Funktion zu sein) attributes() umschreiben, sodass ihr ein Argument übergeben werden kann, oder aber eine neue erfinden, die attributes() aufruft und die Elemente als Eigenschaften des Objektes abspeichert, bevor es sie ausgibt.

    Den Aufruf könnte die neue Methode dann auch jeweils nur beim ersten Mal machen (Nebenläufigkeit und Echtzeitverhalten beachten!), sodass die Eigenschaften nicht immer wieder berechnet werden müssen.

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
     ☻_
    /▌
    / \ Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de
    1. Hi
      Also das ganze ist Teil von simpleXml, hab ich nicht selbst gemacht.
      Mich hat nur an dieser Stelle interessiert ob ich so ein Array gleich weiterverwenden kann oder nicht.
      Ein Problem ists nicht wirklich wenn es nicht geht, wär halt anders schöner gewesen.
      Danke fürs Anschauen an euch!

      1. Hello,

        Also das ganze ist Teil von simpleXml, hab ich nicht selbst gemacht.

        Das war mir schon klar. Meine Idee war eher, die Klasse simpleXml passend zu erweitern. Das müsste doch gehen, oder?

        Aber vermutlich wäre es für diese Aufgabe mit Kanonen auf Spatzen geschossen?

        Liebe Grüße aus dem schönen Oberharz

        Tom vom Berg

        --
         ☻_
        /▌
        / \ Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
        1. Hi!

          Also das ganze ist Teil von simpleXml, hab ich nicht selbst gemacht.
          Das war mir schon klar. Meine Idee war eher, die Klasse simpleXml passend zu erweitern. Das müsste doch gehen, oder?

          Schon, aber was nützt es? Nichts, denn man kann es nicht auf die Art der C#-Extension Methods machen. Mit denen kann man bestehende Klassen direkt "erweitern", ohne dass man den Code der Klasse selbst ändern muss oder dass eine abgeleitete Klasse entstanden ist, die man - und das ist der entscheidende Punkt - zwar selbst verwenden kann, die aber nicht von der bestehenden Implementation verwendet wird. Diese verwendet nach wie vor Objekte der Klasse SimpleXMLElement, um den Objektbaum aus einem XML-Dokument zu erstellen.

          Lo!

    2. Hi!

      $attributes = $xmlObject->xmlElement[0]->attributes();
      echo $attributes["Name"];
      Kann man daraus etwas einzeiliges machen, in der Art $xmlObject->xmlElement[0]->attributes()["Name"]; ? Habs nämlich bisher nicht geschafft.

      Dazu müsstest Du die Methode (eigentlich scheint es ja sowieso eine Funktion zu sein) attributes() umschreiben,

      Es ist eine Methode und zwar von SimpleXMLElement. Umschreiben ist nur durch Ändern des Codes von PHP selbst möglich ...

      Das ist aber nicht notwendig, denn man kann auch auf die Attribute zugreifen, ohne die Methode attributes() zu verwenden:

      $name = (string)$xmlObject->xmlElement[0]['Name'];

      Lo!

      1. Hello,

        $attributes = $xmlObject->xmlElement[0]->attributes();
        echo $attributes["Name"];
        Kann man daraus etwas einzeiliges machen, in der Art $xmlObject->xmlElement[0]->attributes()["Name"]; ? Habs nämlich bisher nicht geschafft.

        Dazu müsstest Du die Methode (eigentlich scheint es ja sowieso eine Funktion zu sein) attributes() umschreiben,

        Es ist eine Methode und zwar von SimpleXMLElement.

        Das bezog sich auch auf den Rückgabewert. Ich war der Meinung, dass man Methoden mit Rückgabewerten auch Funktionen nennen müsste. Allerdings spricht die Literatur bei den Get-Akzessoren auch immer nur von Get-Methoden oder Gettern.

        Umschreiben ist nur durch Ändern des Codes von PHP selbst möglich ...

        Das ist aber nicht notwendig, denn man kann auch auf die Attribute zugreifen, ohne die Methode attributes() zu verwenden:

        $name = (string)$xmlObject->xmlElement[0]['Name'];

        Das stellt aber einen erheblichen Eingriff in die Kapselung dar. Da sind wir wieder bei der Unsinnigkeit von OOP unter PHP angelangt ;-P

        Liebe Grüße aus dem schönen Oberharz

        Tom vom Berg

        --
         ☻_
        /▌
        / \ Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
        1. Hi!

          Dazu müsstest Du die Methode (eigentlich scheint es ja sowieso eine Funktion zu sein) attributes() umschreiben,
          Es ist eine Methode und zwar von SimpleXMLElement.
          Das bezog sich auch auf den Rückgabewert. Ich war der Meinung, dass man Methoden mit Rückgabewerten auch Funktionen nennen müsste. Allerdings spricht die Literatur bei den Get-Akzessoren auch immer nur von Get-Methoden oder Gettern.

          Die Unterscheidung zwischen Routienen mit und ohne Rückgabewert gibt es unter anderem bei Pascal, bei PHP sind das alles Funktionen. Und wenn diese Funktionen zu einer Klasse gehören, dann sind es Methoden. Für diese Bezeichnungen spielt es keine Rolle, ob Methoden einen Rückgabewert haben oder nicht.

          $name = (string)$xmlObject->xmlElement[0]['Name'];
          Das stellt aber einen erheblichen Eingriff in die Kapselung dar. Da sind wir wieder bei der Unsinnigkeit von OOP unter PHP angelangt ;-P

          Was hat eine generell angenommene Unsinnigkeit mit einer konkreten Implementierung zu tun? Es gibt sicher einige Argumente gegen die Art und Weise, wie SimpleXML aufgebaut ist und wie (teilweise nicht einfach nachvollziehbar) die Möglichkeiten der SPL und "magischer" Methoden implementiert wurden. Wenn dir das nicht gefällt, kannst du immer noch die DOM-Extension nutzen. Die ist ordentlich aufgebaut und kommt ohne "Magie" aus.

          Lo!

        2. Hi,

          $name = (string)$xmlObject->xmlElement[0]['Name'];

          Das stellt aber einen erheblichen Eingriff in die Kapselung dar. Da sind wir wieder bei der Unsinnigkeit von OOP unter PHP angelangt ;-P

          Ich habe nicht nachgesehen, aber es ist nicht zwingend notwendig, dass der Rückgabewert von $xmlObject->xmlElement[0] ein Array ist. Es reicht, wenn es das Array-Interface implementiert und somit die OffsetGet-Methode den Getter für "Name" ersetzt. Das wäre immer noch "gültiges OOP".

          Beispiel (nicht getestet):

            
            
          class MyBean implements ArrayAccess {  
            private $bla;  
            public getBla() { return $this->bla; }  
            public setBla($_bla) { $this->bla = $_bla; echo $_bla; }  
            
            private function getFuncName($key, $get = 1) {  
              $key = ($get ? 'g' : 's') . 'et' . ucfirst(strtolower($key));  
            }  
            
            public function offsetExists($key) {  
              return is_callable($this, $this->getFuncName($key));  
              //return method_exists($this, $key); // damit würden private Methoden aufrufbar werden  
            }  
            
            public function offsetGet($key) {  
              if (! $this->offsetExists($key))  
                throw new Exception('Member ' . $key . ' does not exist');  
            
              return $this->{$this->getFuncName($key)}();  
            }  
            
            public function offsetSet($key, $val) {  
              if (! $this->offsetExists($key))  
                throw new Exception('Member ' . $key . ' does not exist');  
            
              return $this->{$this->getFuncName($key, 0)}($val);  
            }  
            
            public function offsetUnset($key) {  
              if (! $this->offsetExists($key))  
                throw new Exception('Member ' . $key . ' does not exist');  
            
              return $this->{$this->getFuncName($key, 0)}(null);  
            }  
          }  
            
          $bean = new MyBean();  
          $bean['bla'] = 'blub';  
          // ruft $bean->setBla('blub') auf und führt darin das "echo" aus  
          
          

          Reflexion machts möglich. Kapselung ist im Wesentlichen nicht verletzt, da es nicht möglich ist, die Eigenschaft 'bla' zu setzen, ohne den Getter/Setter aufzurufen.

          Aber ich vergaß, dass du mit deiner Aussage wieder nur versucht hast, deinen Standpunkt bzgl. OOP zu verteidigen.

          Bis die Tage,
          Matti

          1. Hello Matti,

            Aber ich vergaß, dass du mit deiner Aussage wieder nur versucht hast, deinen Standpunkt bzgl. OOP zu verteidigen.

            Jeder Spaß hat aber auch einen ernsten Hintergrund ;-)

            Danke deshalb für Deine Anregungen.

            Liebe Grüße aus dem schönen Oberharz

            Tom vom Berg

            --
             ☻_
            /▌
            / \ Nur selber lernen macht schlau
            http://bergpost.annerschbarrich.de
  3. Hi Encoder,

    Kann man daraus etwas einzeiliges machen, in der Art $xmlObject->xmlElement[0]->attributes()["Name"]; ? Habs nämlich bisher nicht geschafft.

    das nennt sich "Array dereferencing" und soll in der nächsten großen PHP-Version (ich weiß gar nicht, ob die Versionsnummer inzwischen feststeht, 5.4, 6.0?) enthalten sein. Es gibt dafür ein RFC bei PHP und implementiert ist das wohl auch schon ("Added array dereferencing support. (Felipe)".

    Gruß,
    Andreas.

    1. Hello Andreas,

      Kann man daraus etwas einzeiliges machen, in der Art $xmlObject->xmlElement[0]->attributes()["Name"]; ? Habs nämlich bisher nicht geschafft.

      das nennt sich "Array dereferencing" und soll in der nächsten großen PHP-Version (ich weiß gar nicht, ob die Versionsnummer inzwischen feststeht, 5.4, 6.0?) enthalten sein. Es gibt dafür ein RFC bei PHP und implementiert ist das wohl auch schon ("Added array dereferencing support. (Felipe)".

      Na, hoffentlich enthält das zugehörige Handbuchkapitel dann auch einen Satz über die Sinnhaftigkeit/Unsinnigkeit, ein (großes) Array mittels einer Funktion immer wieder berechnen zu lassen, um dann nur einen einzigen Wert daraus zu extrahieren

      Anderenfalls müsste das Array einfach nach der ersten Berechnung im Speicher gehalten werden und eine "Dirty-Erkennung" eingebaut werden. Das ist aber auch nicht immer die bessere Lösung...

      Oder habe ich da jetzt 'was übersehen?

      Liebe Grüße aus dem schönen Oberharz

      Tom vom Berg

      --
       ☻_
      /▌
      / \ Nur selber lernen macht schlau
      http://bergpost.annerschbarrich.de