Ottieni proprietà della classe PHP per stringa
-
03-07-2019 - |
Domanda
Come posso ottenere 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');
Soluzione
In questo modo
<?php
$prop = 'Name';
echo $obj->$prop;
Oppure, se hai il controllo sulla classe, implementa ArrayAccess interfaccia e basta fare questo
echo $obj['Name'];
Altri suggerimenti
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};
// ...
}
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 del genere? 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à. In questo modo:
$name = 'Name';
$obj->$name = 'something';
$get = $obj->$name;
È semplice, $ obj- > {$ obj- > Name} 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, anche l'uso della parentesi graffa mi ha aiutato ...
esempio con istanza di codice ottenere l'istanza
in una classe di libreria di provenienza chiamata qualcosa con un'istanza di classe genitore
$this->someClass='something';
$this->someID=34;
la classe di libreria che deve provenire da un'altra classe anche con l'istanza parent
echo $this->CI->{$this->someClass}->{$this->someID};
Potrebbero esserci risposte a questa domanda, ma potresti voler vedere queste migrazioni su PHP 7
fonte: php.net
Proprio come un'aggiunta: In questo modo puoi 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);
object(stdClass)#1 (2) { ["a b"]=> int(1) ["x y"]=> int(2) }(non che dovresti, ma nel caso dovessi).
Se vuoi fare cose anche più fantasiose, dovresti esaminare reflection
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 tentare di impostare o ottenere un membro che non è disponibile.
Potresti 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;
}
Utilizzo:
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: nessuna valutazione. essere vecchi in questa lingua.