2009-04-30 20 views

Respuesta

188

gusta esta

<?php 

$prop = 'Name'; 

echo $obj->$prop; 

O, si usted tiene el control sobre la clase, implementar la interfaz ArrayAccess y simplemente hacer esto

echo $obj['Name']; 
+0

gracias un montón! –

+1

¡Cosas geniales +1, y gracias! –

+0

¿Alguna ventaja de usar la segunda opción sobre la primera? – Clox

7

Algo así como ¿esta? 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; 
    } 
} 
+0

La acaba de probar, funciona bien. –

+1

+1, no sabía que las propiedades del objeto se podían acceder usando cadenas. –

+0

Variables variables - http://php.net/manual/en/language.variables.variable.php –

5

Simplemente almacene el nombre de la propiedad en una variable, y use la variable para acceder a la propiedad. De esta manera:

$name = 'Name'; 

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

Lo que preguntas sobre se llama Variable Variables. Todo lo que necesita hacer es almacenar la cadena en una variable y acceder a él de este 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 
+2

Las variables variables son otra cosa. –

+1

La pregunta es cómo obtener una propiedad de clase (variable) cuando el nombre está contenido en una cadena (variable). ¿O leí mal la pregunta? – matpie

2

Así como una adición: esta manera se puede acceder a las propiedades con nombres que de otro modo 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 es que debería, pero en caso de que tenga que hacerlo).
Si usted quiere hacer las cosas aún más elegante que usted debe buscar en reflection

-7
$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); 

qué edición: antes: el uso de eval (mal) después: No hay eval en absoluto. ser viejo en este idioma.

+0

Este es un consejo muy malo, la función eval() es una herramienta muy peligrosa y te dejará muy vulnerable a los ataques de inyección. http://www.blog.highub.com/php/php-core/php-eval-is-evil/ debería darle cierta información. – ridecar2

+2

Eval es la raíz de todos los males – r4ccoon

+3

¡Elimina esta respuesta y tendrás una insignia! – Thermech

0

Aquí está mi intento. Tiene incorporadas algunas comprobaciones de "estupidez" comunes, asegurándose de que no intente establecer u obtener un miembro que no esté disponible.

Puede mover esas comprobaciones '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"; 

?> 
3

Es simple, $ obj -> {$ obj-> Nombre} las llaves envolverá la propiedad al igual que 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 también ayudó ...

ejemplo, con CodeIgniter conseguir instancia

en una clase de biblioteca con fuente llamado algo con una instancia de la clase padre

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

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

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

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}; 
    // ... 
} 
+0

No funciona en php reciente. –

+6

Esta es la única forma si desea acceder a un valor de matriz '$ this -> {$ property} [$ name]', de lo contrario '$ this -> $ property [$ name]' arrojará un error – goyote

+5

Estoy usando PHP 5.4.8 y está funcionando. – b01

0

Lo que hace esta función es que comprueba si la propiedad existe en esta clase de cualquiera de su hijo, y si es así obtiene el valor de lo contrario devuelve 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); 
1

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

backward incompatible change

fuente: php.net

0

En caso de que alguien más quiera encontrar una propiedad profunda o Para una 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 llamar con algo como:

$propertyString = getXMLAttribute('string'); // '@Foo/Bar/baz' 
$propertyString = substr($propertyString, 1); 
$moduleCaller = new ModuleCaller(); 
echo $moduleCaller->callModule($propertyString); 
Cuestiones relacionadas