2009-04-30 6 views

Répondre

188

Vous aimez cette

<?php 

$prop = 'Name'; 

echo $obj->$prop; 

Ou, si vous avez le contrôle sur la classe, mettre en œuvre l'interface ArrayAccess et juste faire ce

echo $obj['Name']; 
+0

Merci un bouquet! –

+1

Cool stuff +1, et merci! –

+0

Tout avantage d'utiliser la deuxième option par rapport à la première? – Clox

7

Quelque chose comme ce? Je n'ai pas testé mais cela devrait fonctionner correctement.

function magic($obj, $var, $value = NULL) 
{ 
    if($value == NULL) 
    { 
     return $obj->$var; 
    } 
    else 
    { 
     $obj->$var = $value; 
    } 
} 
+0

Juste testé, fonctionne très bien. –

+1

+1, ne connaissait pas les propriétés d'objet pouvant être accédées à l'aide de chaînes. –

+0

Variables variables - http://php.net/manual/fr/language.variables.variable.php –

5

magasin juste le nom de la propriété dans une variable, et utiliser la variable pour accéder à la propriété. Comme ceci:

$name = 'Name'; 

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

Ce que vous demandez à propos de est appelé Variable Variables. Tout ce que vous devez faire est de stocker votre chaîne dans une variable et accéder comme si:

$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 
+2

Les variables variables sont une autre chose. –

+1

La question est comment obtenir une propriété de classe (variable) lorsque le nom est contenu dans une chaîne (variable). Ou ai-je mal interprété la question? – matpie

2

Tout 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 que vous devrait, mais au cas où vous devez).
Si vous voulez faire des choses même colombophile vous devriez regarder dans reflection

-7
$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 modifier: avant: utiliser eval (mal) après: pas du tout eval. être vieux dans cette langue.

+0

C'est un très mauvais conseil, la fonction eval() est un outil très dangereux et vous laissera extrêmement vulnérable aux attaques par injection. http://www.blog.highub.com/php/php-core/php-eval-is-evil/ devrait vous donner quelques informations. – ridecar2

+2

Eval est la racine de tout mal – r4ccoon

+3

Supprimer cette réponse et vous aurez un badge! – Thermech

0

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

Vous pouvez déplacer ces contrôles 'property_exists' respectivement vers __set et __get 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"; 

?> 
3

Il est simple, $ obj -> {$ obj-> Nom} les accolades vont envelopper la propriété comme une variable variable.

Ceci a été une première recherche. Mais n'a pas résolu ma question, qui utilisait $ this. Dans le cas de ma situation en utilisant le support bouclé a également aidé ...

exemple avec CodeIgniter get instance

dans une chose classe bibliothèque sourced appelée avec une instance de classe parente

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

la classe bibliothèque besoin de la source d'une autre classe aussi avec les parents par exemple

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

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

Ne fonctionne pas dans php récent. –

+6

Ceci est le seul moyen si vous voulez accéder à une valeur de tableau '$ this -> {$ propriété} [$ name]', sinon '$ this -> $ propriété [$ name]' jettera une erreur – goyote

+5

Je suis en utilisant PHP 5.4.8 et ça marche. – b01

0

Qu'est-ce que cette fonction n'est-il vérifie si la propriété existe sur cette classe d'un de ses enfants de et si c'est le cas, il obtient la valeur sinon il renvoie null. Alors maintenant les propriétés sont optionnelles 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); 
1

Il pourrait y avoir des réponses à cette question, mais vous pouvez vouloir voir ces migrations vers PHP 7

backward incompatible change

source: php.net

0

Dans le cas où quelqu'un d'autre veut trouver une propriété profonde o Avec une profondeur inconnue, je suis arrivé avec le dessous sans avoir besoin de parcourir 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);