it-swarm.com.de

Erhalten PHP Klasseneigenschaft nach Zeichenfolge

Wie bekomme ich eine Eigenschaft in einem PHP basierend auf einer Zeichenfolge? Ich werde es magic nennen. Was ist also magic?

$obj->Name = 'something';
$get = $obj->Name;

wäre wie...

magic($obj, 'Name', 'something');
$get = magic($obj, 'Name');
118
Daniel A. White

So was

<?php

$prop = 'Name';

echo $obj->$prop;

Wenn Sie die Klasse selbst steuern können, implementieren Sie die ArrayAccess - Schnittstelle und tun Sie dies einfach

echo $obj['Name'];
209
Peter Bailey

Wenn Sie auf die Eigenschaft zugreifen möchten, ohne eine Zwischenvariable zu erstellen, verwenden Sie die {}-Notation:

$something = $object->{'something'};

So können Sie beispielsweise den Eigenschaftsnamen in einer Schleife erstellen:

for ($i = 0; $i < 5; $i++) {
    $something = $object->{'something' . $i};
    // ...
}
135
this.lau_

Was Sie fragen, heißt Variable Variablen . Alles, was Sie tun müssen, ist, Ihren String in einer Variablen zu speichern und wie folgt darauf zuzugreifen:

$Class = 'MyCustomClass';
$Property = 'Name';
$List = array('Name');

$Object = new $Class();

// All of these will echo the same property
echo $Object->$Property;  // Evaluates to $Object->Name
echo $Object->{$List[0]}; // Use if your variable is in an array
9
matpie

Etwas wie das? Ich habe es nicht getestet, sollte aber gut funktionieren.

function magic($obj, $var, $value = NULL)
{
    if($value == NULL)
    {
        return $obj->$var;
    }
    else
    {
        $obj->$var = $value;
    }
}
7
Ólafur Waage

Speichern Sie einfach den Eigenschaftsnamen in einer Variablen und verwenden Sie die Variable, um auf die Eigenschaft zuzugreifen. So was:

$name = 'Name';

$obj->$name = 'something';
$get = $obj->$name;
5
Jon Benedicto

Es ist einfach: $ obj -> {$ obj-> Name} Die geschweiften Klammern umschließen die Eigenschaft ähnlich einer Variablenvariablen.

Dies war eine Top-Suche. Aber meine Frage, die $ $ verwendet, wurde nicht gelöst. Im Falle meiner Umstände half die geschweifte Klammer auch ... 

beispiel mit Code Igniter get Instanz

in einer Bibliothek mit Quellenangabe wurde etwas mit einer übergeordneten Klasseninstanz aufgerufen

$this->someClass='something';
$this->someID=34;

die Bibliotheksklasse muss auch von der Elterninstanz aus einer anderen Klasse stammen

echo $this->CI->{$this->someClass}->{$this->someID};
3
Mark Allen

Nur als Zusatz: Auf diese Weise können Sie auf Eigenschaften mit Namen zugreifen, die sonst unbrauchbar wären

$ x = neue StdClass;

$ prop = 'a b'; $ x -> $ prop = 1; $ x -> {'x y'} = 2; var_dump ($ x);</ pre>

object (stdClass) # 1 (2) {
 ["a b"] => 
 int (1) 
 ["x y"] => 
 int (2) 
}
(Nicht, dass Sie sollten, aber falls Sie müssen).
Wenn Sie noch schickere Sachen machen wollen, sollten Sie in Reflektion nachschauen.

2
VolkerK

Möglicherweise gibt es Antworten auf diese Frage, aber Sie möchten vielleicht die Migration zu PHP 7 sehen

backward incompatible change

quelle: php.net

2

Für den Fall, dass jemand anderes eine tiefe Eigenschaft von unbekannter Tiefe finden möchte, habe ich mir das unten ausgedacht, ohne alle bekannten Eigenschaften aller Kinder durchlaufen zu müssen. 

B. $ Foo-> Bar-> Baz oder $ Foo-> Baz oder $ Foo-> Bar-> Baz-> Dave suchen, wobei $ path eine Zeichenfolge wie 'foo/bar/baz' ist.

public function callModule($pathString, $delimiter = '/'){

    //split the string into an array
    $pathArray = explode($delimiter, $pathString);

    //get the first and last of the array
    $module = array_shift($pathArray);
    $property = array_pop($pathArray);

    //if the array is now empty, we can access simply without a loop
    if(count($pathArray) == 0){
        return $this->{$module}->{$property};
    }

    //we need to go deeper
    //$tmp = $this->Foo
    $tmp = $this->{$module};

    foreach($pathArray as $deeper){
        //re-assign $tmp to be the next level of the object
        // $tmp = $Foo->Bar --- then $tmp = $Bar->baz
        $tmp = $tmp->{$deeper};
    }

    //now we are at the level we need to be and can access the property
    return $tmp->{$property};

}

Und dann mit so etwas anrufen:

$propertyString = getXMLAttribute('string'); // '@Foo/Bar/baz'
$propertyString = substr($propertyString, 1);
$moduleCaller = new ModuleCaller();
echo $moduleCaller->callModule($propertyString);
0

Hier ist mein Versuch. Es gibt einige gängige "Dummheitsprüfungen", die sicherstellen, dass Sie nicht versuchen, ein Mitglied festzulegen oder zu erhalten, das nicht verfügbar ist.

Sie können diese Checks für 'property_exists' nach __set bzw. __get verschieben und sie direkt in magic () aufrufen.

<?php

class Foo {
    public $Name;

    public function magic($member, $value = NULL) {
        if ($value != NULL) {
            if (!property_exists($this, $member)) {
                trigger_error('Undefined property via magic(): ' .
                    $member, E_USER_ERROR);
                return NULL;
            }
            $this->$member = $value;
        } else {
            if (!property_exists($this, $member)) {
                trigger_error('Undefined property via magic(): ' .
                    $member, E_USER_ERROR);
                return NULL;
            }
            return $this->$member;
        }
    }
};

$f = new Foo();

$f->magic("Name", "Something");
echo $f->magic("Name") , "\n";

// error
$f->magic("Fame", "Something");
echo $f->magic("Fame") , "\n";

?>
0
Nick Presta

Diese Funktion prüft, ob die Eigenschaft in dieser Klasse eines Kindes vorhanden ist, und wenn dies der Fall ist, wird ansonsten der Wert null zurückgegeben. Die Eigenschaften sind also optional und dynamisch.

/**
 * check if property is defined on this class or any of it's childes and return it
 *
 * @param $property
 *
 * @return bool
 */
private function getIfExist($property)
{
    $value = null;
    $propertiesArray = get_object_vars($this);

    if(array_has($propertiesArray, $property)){
        $value = $propertiesArray[$property];
    }

    return $value;
}

Verwendungszweck:

const CONFIG_FILE_PATH_PROPERTY = 'configFilePath';

$configFilePath = $this->getIfExist(self::CONFIG_FILE_PATH_PROPERTY);
0
Mahmoud Zalt