Wie schreibe ich dynamisch einen PHP-Objekteigenschaftsnamen?

81

Ich habe Objekteigenschaften in meinem Code, die folgendermaßen aussehen:

$obj ->field_name_cars[0];
$obj ->field_name_clothes[0];

Das Problem ist, dass ich Hunderte von Feldnamen habe und den Eigenschaftsnamen dynamisch schreiben muss. Andernfalls sind der Objektname und die Schlüssel für die Eigenschaft immer identisch. Also habe ich versucht:

$obj -> $field[0];

In der Hoffnung, dass der Name der Eigenschaft dynamisch geändert wird und auf die richtigen Werte zugegriffen wird. Aber ich bekomme immer wieder 'undefined property $ field in stdClass :: $ field;

Mehr oder weniger versuche ich, das PHP dynamisch zu schreiben, bevor es ausgeführt wird, damit es die richtigen Werte ausgeben kann. Gedanken darüber, wie man das angeht?

user658182
quelle

Antworten:

205

Update für PHP 7.0

In PHP 7 wurden Änderungen am Umgang mit indirekten Variablen und Eigenschaften auf Parser-Ebene eingeführt ( weitere Informationen finden Sie im entsprechenden RFC ). Dies bringt das tatsächliche Verhalten näher an das erwartete und bedeutet, dass in diesem Fall $obj->$field[0]das erwartete Ergebnis erzielt wird.

In Fällen, in denen das (jetzt verbesserte) Standardverhalten unerwünscht ist, können geschweifte Klammern weiterhin verwendet werden, um es wie unten gezeigt zu überschreiben.

Ursprüngliche Antwort

Schreiben Sie den Zugriff wie folgt:

$obj->{$field}[0]

Dieser Trick "Mit geschweiften Klammern einschließen" ist in PHP nützlich, wenn aufgrund variabler Variablen Mehrdeutigkeiten bestehen.

Betrachten Sie den Anfangscode $obj->$field[0]- bedeutet dies "Zugriff auf die Eigenschaft, in der der Name angegeben ist $field[0]" oder "Zugriff auf das Element mit dem Schlüssel 0der Eigenschaft, in der der Name angegeben ist $field"? Mit den geschweiften Klammern können Sie explizit sein.

Jon
quelle
Diese rohe Anweisung funktioniert in meinem Code: echo $ json_dump-> Geometrie [6] -> obs [2] -> hayabusa2-> delay_from; Aber ich kann es nicht "simulieren", indem ich "Geometrie [6] -> obs [2] -> hayabusa2-> delay_from" $ path zuweise und echo $ json_dump -> {$ path} verwende. Ich erhalte "Undefined property: stdClass: : $ Geometrie [6] "
Jumpjack
31

Ich denke, Sie suchen nach einer Typennotation mit variablen Variablen, die beim Zugriff auf Werte von anderen Arrays / Objekten am besten mit der folgenden Syntax für geschweifte Klammern erreicht wird:

$obj->{field[0]}
Mike Brant
quelle
12

Die magische Methode __get ist dein Freund:

class MyClass
{
   private $field = array();

   public function __get($name)
   {
      if(isset($this->field[$name]))
        return $this->field[$name];
      else
        throw new Exception("$name dow not exists");
   }
}

Verwendung:

$myobj = new MyClass();
echo $myobj->myprop;

Erläuterung: Alle Ihre Felddaten werden in einem Array gespeichert. Wenn Sie auf $myobj->mypropdiese Eigenschaft zugreifen , ist sie in der Klasse offensichtlich nicht vorhanden. Dort __getheißt es. __getsucht den Namen im fieldArray und gibt den richtigen Wert zurück.

JvdBerg
quelle
3
Tu das nicht. __get-Funktionen sind Leistungsprobleme, die Sie nach Möglichkeit vermeiden sollten, zusätzlich zu einigen schwerwiegenden Problemen mit unerwartetem Verhalten. Dieses Beispiel ist besonders beängstigend, da es eine Ausnahme auslöst, die schwerwiegende App-Probleme verursachen kann, wenn der Entwickler nicht vorhat, auf ein nicht vorhandenes Attribut zuzugreifen, um eine Ausnahme auszulösen, und einen einfachen Attributzugriff in einen potenziell schwerwiegenden Fehler verwandelt.
Moberemk
0

aboulfazl, da PHP 5.3.3-Methoden mit demselben Namen wie die Klasse nicht als Konstruktor behandelt werden!

    YourClass
    {
        public $any = false;

        public function __construct($any = null)
        {
            $this->any = (is_null($any) ? $this->any : $any);
        }
    }

Dies funktioniert, wurde aber nicht vom Themeninhaber gefragt, Jon gibt die Antwort!

Everterstraat
quelle
0

Ich habe an Code gearbeitet, der dynamisch erstellte Objekteigenschaften verwendet. Ich fand die Verwendung dynamisch erstellter Objekteigenschaften ziemlich cool (meiner Meinung nach wahr). Die Ausführung meines Programms dauerte jedoch 7 Sekunden. Ich habe die dynamischen Objekteigenschaften entfernt und sie ersetzt, die als Teil jeder Klasse deklariert wurden (in diesem Fall öffentlich). Die CPU-Zeit stieg von über 7 Sekunden auf 0,177 Sekunden. Das ist ziemlich umfangreich.

Es ist möglich, dass ich bei der Verwendung dynamischer Objekteigenschaften etwas falsch gemacht habe. Es ist auch möglich, dass meine Konfiguration auf irgendeine Weise beschädigt ist. Natürlich sollte ich sagen, dass ich eine sehr einfache Vanille-PHP-Konfiguration auf meinem Computer habe.

Peter Schaeffer
quelle
0

Heute stehe ich vor dieser Herausforderung. Am Ende hatte ich diesen Entwicklungsstil

$countTickets = new \stdClass;

foreach ($tickets as $key => $value) {

    if(!isset($countTickets->total)){
        $countTickets->total = 0;
    }

    if(!isset($countTickets->{$value['categoryname']})){
        $countTickets->{$value['categoryname']} = 0;
    }

    $countTickets->total += $value['number'];
    $countTickets->{$value['categoryname']} += $value['number']; 
}
Jordan Georgiadis
quelle
-4

Am besten können Sie die Instanz der PHP-Standardklasse Object verwenden, um ihr dynamisch Eigenschaften zuzuweisen

$inst=new \StdClass;
$inst->any_property = '';
Boss Andrew
quelle
-6

Mit Vererbung. zum Beispiel:

YourClass extends stdClass {
   public function YourClass() {
      $this->AnyProperty="any";
   }
}

Jetzt wird AnyProperty dynamisch deklariert.

aboulfazl
quelle