Pregunta

¿Cómo obtengo una propiedad en un PHP basado en una cadena? Lo llamaré magic . Entonces, ¿qué es magic ?

$obj->Name = 'something';
$get = $obj->Name;

sería como ...

magic($obj, 'Name', 'something');
$get = magic($obj, 'Name');
¿Fue útil?

Solución

Me gusta esto

<?php

$prop = 'Name';

echo $obj->$prop;

O, si tiene control sobre la clase, implemente el ArrayAccess Interfaz y simplemente haz esto

echo $obj['Name'];

Otros consejos

Si desea acceder a la propiedad sin crear una variable intermedia, use la notación {} :

$something = $object->{'something'};

Eso también le permite crear el nombre de la propiedad en un bucle, por ejemplo:

for ($i = 0; $i < 5; $i++) {
    $something = $object->{'something' . $i};
    // ...
}

Lo que estás preguntando se llama Variables variables . Todo lo que necesita hacer es almacenar su cadena en una variable y acceder a ella de esta manera:

$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. Así:

$name = 'Name';

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

Es simple, $ obj- > {$ obj- > Name} los corchetes encierran la propiedad como una variable variable.

Esta fue una búsqueda superior. Pero no resolví mi pregunta, que estaba usando $ esto. En el caso de mi circunstancia, usar el corchete también ayudó ...

ejemplo con instancia de Code Igniter get

en una clase de biblioteca derivada llamada algo con una instancia de clase padre

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

la clase de biblioteca que necesita fuente de otra clase también con la instancia de los padres

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

Es posible que haya respuestas a esta pregunta, pero es posible que desee ver estas migraciones a PHP 7

cambio incompatible con versiones anteriores

fuente: php.net

Sólo como una adición: De esta manera, puede acceder a las propiedades con nombres que de otra manera serían inutilizables

$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)
}
(no como debería, pero en caso de que tenga que hacerlo).
Si quieres hacer cosas aún más sofisticadas, deberías consultar reflexión

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 algunos controles comunes de "estupidez" incorporados, asegurándose de que no intentes establecer u obtener un miembro que no esté disponible.

Puedes mover esos cheques de 'propiedades_existentes' a __set y __get respectivamente y llamarlos 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 el valor nulo. Así que 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 (el mal) después: no eval en absoluto. ser viejo en este idioma.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top