Come ottengo una proprietà in un PHP basata su una stringa? Lo chiamerò magic. Quindi cos'è magic?
$obj->Name = 'something';
$get = $obj->Name;
sarebbe come...
magic($obj, 'Name', 'something');
$get = magic($obj, 'Name');
Come ottengo una proprietà in un PHP basata su una stringa? Lo chiamerò magic. Quindi cos'è magic?
$obj->Name = 'something';
$get = $obj->Name;
sarebbe come...
magic($obj, 'Name', 'something');
$get = magic($obj, 'Name');
Risposte:
Come questo
<?php
$prop = 'Name';
echo $obj->$prop;
Oppure, se si ha il controllo sulla classe, implementare l' interfaccia ArrayAccess e farlo
echo $obj['Name'];
ArrayAccess, Countablee una delle interfacce iteratore, è per lo più indistinguibile da una normalearray()
Se si desidera accedere alla proprietà senza creare una variabile intermedia, utilizzare la {}notazione:
$something = $object->{'something'};
Ciò consente anche di creare il nome della proprietà in un ciclo, ad esempio:
for ($i = 0; $i < 5; $i++) {
$something = $object->{'something' . $i};
// ...
}
$this->{$property}[$name], altrimenti si $this->$property[$name]genererà un errore
$this->$property[$name]potrebbe effettivamente avere successo, anche se è probabile che si tratti di un bug. $nameviene eseguito il cast silenzioso su un numero intero. Nel caso di una stringa non numerica questo è 0. Quindi questo indice di stringa del valore di $propertyviene utilizzato come nome della proprietà. Se $propertycontiene il valore "abc", questo farà riferimento alla proprietà $this->a(indice 0). Se esiste una proprietà del genere, ciò avrà esito positivo.
Quello che stai chiedendo si chiama Variabili variabili . Tutto quello che devi fare è archiviare la stringa in una variabile e accedervi in questo modo:
$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
Qualcosa come questo? Non l'ho provato ma dovrebbe funzionare bene.
function magic($obj, $var, $value = NULL)
{
if($value == NULL)
{
return $obj->$var;
}
else
{
$obj->$var = $value;
}
}
Basta archiviare il nome della proprietà in una variabile e utilizzare la variabile per accedere alla proprietà. Come questo:
$name = 'Name';
$obj->$name = 'something';
$get = $obj->$name;
Potrebbero esserci risposte a questa domanda, ma potresti voler vedere queste migrazioni su PHP 7

fonte: php.net
È semplice, $ obj -> {$ obj-> Nome} le parentesi graffe avvolgeranno la proprietà come una variabile variabile.
Questa è stata una ricerca top. Ma non ho risolto la mia domanda, che utilizzava $ this. Nel caso delle mie circostanze l'uso della parentesi graffa mi ha anche aiutato ...
esempio con Code Igniter ottenere istanza
in una classe di libreria di provenienza chiamata qualcosa con un'istanza di classe padre
$this->someClass='something';
$this->someID=34;
la classe della libreria che deve provenire da un'altra classe anche con l'istanza parent
echo $this->CI->{$this->someClass}->{$this->someID};
Solo come aggiunta: in questo modo è possibile accedere a proprietà con nomi che sarebbero altrimenti inutilizzabili
$ x = new StdClass;$ prop = 'a b'; $ x -> $ prop = 1; $ x -> {'x y'} = 2; var_dump ($ x);
oggetto (stdClass) # 1 (2) {
["a b"] =>
int (1)
["x y"] =>
int (2)
}(non che dovresti, ma nel caso dovessi). Nel caso in cui qualcun altro volesse trovare una proprietà profonda di profondità sconosciuta, mi è venuta in mente la seguente senza dover ricorrere a tutte le proprietà conosciute di tutti i bambini.
Ad esempio, per trovare $ Foo-> Bar-> baz o $ Foo-> baz o $ Foo-> Bar-> Baz-> dave, dove $ path è una stringa come '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};
}
E poi chiama con qualcosa del tipo:
$propertyString = getXMLAttribute('string'); // '@Foo/Bar/baz'
$propertyString = substr($propertyString, 1);
$moduleCaller = new ModuleCaller();
echo $moduleCaller->callModule($propertyString);
Ecco il mio tentativo. Ha alcuni controlli comuni di "stupidità" integrati, che assicurano di non provare a impostare o ottenere un membro che non è disponibile.
Puoi spostare i controlli 'property_exists' rispettivamente su __set e __get e chiamarli direttamente in 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";
?>
Ciò che questa funzione fa è controlla se la proprietà esiste su questa classe di una qualsiasi di suo figlio, e in tal caso ottiene il valore, altrimenti restituisce null. Quindi ora le proprietà sono opzionali e dinamiche.
/**
* 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;
}
Uso:
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);
perché modificare: prima: usando eval (male) dopo: no eval affatto. essere vecchi in questa lingua.