¿Cómo obtengo una propiedad en un PHP basada en una cadena? Lo llamaré magic
. Entonces que es magic
?
$obj->Name = 'something';
$get = $obj->Name;
seria como...
magic($obj, 'Name', 'something');
$get = magic($obj, 'Name');
¿Cómo obtengo una propiedad en un PHP basada en una cadena? Lo llamaré magic
. Entonces que es magic
?
$obj->Name = 'something';
$get = $obj->Name;
seria como...
magic($obj, 'Name', 'something');
$get = magic($obj, 'Name');
Respuestas:
Me gusta esto
<?php
$prop = 'Name';
echo $obj->$prop;
O, si tiene control sobre la clase, implemente la interfaz ArrayAccess y simplemente haga esto
echo $obj['Name'];
ArrayAccess
, Countable
y una de las interfaces de iterador, es casi imposible de distinguir de lo normalarray()
Si desea acceder a la propiedad sin crear una variable intermedia, use la {}
notación:
$something = $object->{'something'};
Eso también le permite construir el nombre de la propiedad en un bucle, por ejemplo:
for ($i = 0; $i < 5; $i++) {
$something = $object->{'something' . $i};
// ...
}
$this->{$property}[$name]
, de lo contrario $this->$property[$name]
se generará un error
$this->$property[$name]
realmente tenga éxito, aunque es probable que sea un error. $name
se lanza silenciosamente a un número entero. En el caso de una cadena no numérica, esto es 0
. Entonces este índice de cadena del valor de $property
se usa como el nombre de la propiedad. Si $property
contiene el valor "abc", esto se referirá a la propiedad $this->a
(índice 0). Si existe tal propiedad, esto tendrá éxito.
Lo que estás preguntando se llama Variable Variables . Todo lo que necesita hacer es almacenar su cadena en una variable y acceder a ella así:
$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
¿Algo como esto? No lo he probado, pero debería funcionar bien.
function magic($obj, $var, $value = NULL)
{
if($value == NULL)
{
return $obj->$var;
}
else
{
$obj->$var = $value;
}
}
Simplemente almacene el nombre de la propiedad en una variable y use la variable para acceder a la propiedad. Me gusta esto:
$name = 'Name';
$obj->$name = 'something';
$get = $obj->$name;
Puede haber respuestas a esta pregunta, pero es posible que desee ver estas migraciones a PHP 7
fuente: php.net
Es simple, $ obj -> {$ obj-> Name} los corchetes envolverán la propiedad como una variable variable.
Esta fue una búsqueda superior. Pero no resolvió mi pregunta, que estaba usando $ this. En el caso de mi circunstancia, usar el soporte rizado también ayudó ...
ejemplo con Code Igniter obtener instancia
en una clase de biblioteca de origen llamada algo con una instancia de clase padre
$this->someClass='something';
$this->someID=34;
la clase de biblioteca que necesita obtener de otra clase también con la instancia de los padres
echo $this->CI->{$this->someClass}->{$this->someID};
Solo como una adición: de esta manera puede acceder a propiedades con nombres que de otro modo serían inutilizables
$ x = nueva 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) }(No es que debas hacerlo, pero en caso de que tengas que hacerlo).
En caso de que alguien más quiera encontrar una propiedad profunda de profundidad desconocida, se me ocurrió lo siguiente sin necesidad de recorrer todas las propiedades conocidas de todos los niños.
Por ejemplo, para encontrar $ Foo-> Bar-> baz, o $ Foo-> baz, o $ Foo-> Bar-> Baz-> dave, donde $ path es una cadena como '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};
}
Y luego llame con algo como:
$propertyString = getXMLAttribute('string'); // '@Foo/Bar/baz'
$propertyString = substr($propertyString, 1);
$moduleCaller = new ModuleCaller();
echo $moduleCaller->callModule($propertyString);
Aquí está mi intento. Tiene algunas comprobaciones comunes de 'estupidez' incorporadas, asegurándose de que no intente establecer u obtener un miembro que no esté disponible.
Puede mover esas verificaciones 'property_exists' a __set y __get respectivamente y llamarlas directamente dentro de 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";
?>
Lo que hace esta función es verificar si la propiedad existe en esta clase de cualquiera de sus hijos, y si es así, obtiene el valor, de lo contrario, devuelve nulo. Entonces ahora las propiedades son opcionales y dinámicas.
/**
* 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);
por qué editar: antes: usando eval (evil) después: no eval en absoluto. ser viejo en este idioma