Question

Comment obtenir une propriété dans un PHP basé sur une chaîne? Je l'appellerai magique . Alors qu'est-ce que magic ?

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

serait comme ...

magic($obj, 'Name', 'something');
$get = magic($obj, 'Name');
Était-ce utile?

La solution

Comme ceci

<?php

$prop = 'Name';

echo $obj->$prop;

Si vous avez le contrôle de la classe, implémentez ArrayAccess interface et il suffit de faire cela

echo $obj['Name'];

Autres conseils

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

Ce que vous demandez, s'appelle Variables de variable . . 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

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

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

$name = 'Name';

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

C’est simple, $ obj- > {$ obj- & Name} les accolades encapsulent la propriété de manière très similaire à une variable variable.

C’était une recherche en haut. Mais n'a pas résolu ma question, qui utilisait $ ceci. Dans le cas où j’ai eu recours à la parenthèse, cela 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 d'une source provenant d'une autre classe également avec l'instance de parents

echo $this->CI->{$this->someClass}->{$this->someID};

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

modification incompatible avec les versions antérieures

source: php.net

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

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

Au cas où quelqu'un d'autre voudrait trouver une propriété profonde dont la profondeur serait inconnue, j'ai proposé 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 telle que '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};

}

Puis appelez avec quelque chose comme:

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

Voici ma tentative. Il comporte des contrôles communs de "stupidité", assurant que vous n'essayez pas de définir ou d'obtenir un membre qui n'est pas disponible.

Vous pouvez déplacer ces chèques 'property_exists' 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";

?>

Ce que fait cette fonction, c’est qu’elle vérifie si la propriété existe sur cette classe de l’un de ses enfants, et si elle obtient la valeur, sinon elle retourne null. Alors maintenant, les propriétés sont 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;
}

Utilisation:

const CONFIG_FILE_PATH_PROPERTY = 'configFilePath';

$configFilePath = $this->getIfExist(self::CONFIG_FILE_PATH_PROPERTY);
$classname = "myclass";
$obj = new $classname($params);

$variable_name = "my_member_variable";
$val = $obj->$variable_name; //do care about the level(private,public,protected)

$func_name = "myFunction";
$val = $obj->$func_name($parameters);

pourquoi éditer: avant: utiliser eval (evil) après: pas d'évaluation du tout. être vieux dans cette langue.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top