web-dev-qa-db-fra.com

Obtenir PHP propriété de classe par chaîne

Comment obtenir une propriété dans un PHP basée sur une chaîne? Je l'appellerai magic. Alors, quelle est magic?

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

serait comme...

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

Comme ça

<?php

$prop = 'Name';

echo $obj->$prop;

Ou, si vous avez le contrôle de la classe, implémentez l'interface ArrayAccess et procédez comme suit.

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

Si vous souhaitez accéder à la propriété sans créer de variable intermédiaire, utilisez la notation {}:

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

Cela vous permet également de construire le nom de la propriété dans une boucle, par exemple:

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

Ce que vous demandez est appelé Variables variables . Tout ce que vous avez à faire est de stocker votre chaîne dans une variable et d'y accéder comme suit:

$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

Quelque chose comme ça? Je ne l'ai pas testé, mais cela devrait fonctionner correctement.

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

Stockez simplement le nom de la propriété dans une variable et utilisez-la pour accéder à la propriété. Comme ça:

$name = 'Name';

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

C’est simple, $ obj -> {$ obj-> Name} les accolades encapsulent la propriété de la même manière qu’une variable variable.

C'était une recherche top. Mais n'a pas résolu ma question, qui utilisait $ ceci. Dans le cas de ma circonstance, l'utilisation de l'accolade a également aidé ... 

exemple avec Code Igniter get instance

dans une classe de bibliothèque source appelée quelque chose avec une instance de classe parent

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

la classe de bibliothèque ayant besoin de source d'une autre classe également avec l'instance de parents

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

Juste comme un ajout: De cette façon, vous pouvez accéder à des propriétés avec des noms qui seraient autrement inutilisables

$ x = new StdClass;

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

objet (stdClass) # 1 (2) {
 ["a b"] => 
 int (1) 
 ["x y"] => 
 int (2) 
}
(pas que vous devriez, mais au cas où vous devez).
Si vous voulez faire des choses plus sophistiquées, vous devriez regarder dans réflexion

2
VolkerK

Il peut y avoir des réponses à cette question, mais vous voudrez peut-être voir ces migrations vers PHP 7

backward incompatible change

source: php.net

2
Muhammad Maulana

Au cas où quelqu'un d'autre voudrait trouver une propriété profonde de profondeur inconnue, j'ai créé ce qui suit sans avoir à parcourir en boucle toutes les propriétés connues de tous les enfants. 

Par exemple, pour trouver $ Foo-> Bar-> baz, ou $ Foo-> baz, ou $ Foo-> Bar-> Baz-> dave, où $ path est une chaîne comme "foo/bar/baz".

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};

}

Et puis appelez avec quelque chose comme:

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

Voici ma tentative. Il comporte des contrôles communs de «stupidité» intégrés, vous assurant que vous n'essayez pas de définir ou d'obtenir un membre non disponible.

Vous pouvez déplacer les chèques de ces propriétés vers __set et __get respectivement et les appeler directement dans magic ().

<?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

Cette fonction vérifie si la propriété existe dans cette classe de l'un de ses enfants et, dans l'affirmative, obtient la valeur, sinon elle renvoie la valeur null . Les propriétés sont donc facultatives et dynamiques.

/**
 * 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;
}

Usage:

const CONFIG_FILE_PATH_PROPERTY = 'configFilePath';

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