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');
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'];
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 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
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 ça:
$name = 'Name';
$obj->$name = 'something';
$get = $obj->$name;
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};
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
Il peut y avoir des réponses à cette question, mais vous voudrez peut-être voir ces migrations vers PHP 7
source: php.net
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);
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";
?>
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);