Pergunta

Como faço para obter uma propriedade em um PHP baseada em uma corda? Eu vou chamá-lo magic. Então, qual é magic?

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

seria como ...

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

Solução

Como este

<?php

$prop = 'Name';

echo $obj->$prop;

Ou, se você tem controle sobre a classe, implementar o ArrayAccess interface e apenas fazer isso

echo $obj['Name'];

Outras dicas

Se você quiser acessar a propriedade sem criar uma variável intermediária, use a notação {}:

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

Isso também permite que você construa o nome da propriedade em um loop por exemplo:

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

O que você está perguntando sobre é chamado variáveis ??variáveis ?? . Tudo que você precisa fazer é armazenar sua seqüência em uma variável e acessá-lo assim:

$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 isso? Não testei, mas deve funcionar bem.

function magic($obj, $var, $value = NULL)
{
    if($value == NULL)
    {
        return $obj->$var;
    }
    else
    {
        $obj->$var = $value;
    }
}

Apenas armazenar o nome da propriedade em uma variável e usar a variável para acessar a propriedade. Como esta:

$name = 'Name';

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

É simples, $ obj -.> {$ Obj-> Name} as chaves vai embrulhar a propriedade bem como uma variável variável

Esta foi uma pesquisa de topo. Mas não resolveu a minha pergunta, que estava usando $ this. No caso da minha circunstância usando o colchete também ajudou ...

exemplo, com exemplo Código Igniter get

em uma classe da biblioteca de origem chamado algo com uma instância da classe pai

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

a classe biblioteca necessidade de fonte de outra classe também com o exemplo dos pais

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

Pode haver respostas para essa pergunta, mas você pode querer ver essas migrações para PHP 7

mudança incompatível para trás

Fonte: php.net

Assim como um complemento: Desta forma, você pode acessar as propriedades com nomes que seriam de outra forma inutilizável

$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)
}
(não que você deveria, mas no caso de você tem que).
Se você quer fazer coisas ainda mais extravagante que você deve olhar para reflexão

No caso de alguém mais quer encontrar uma propriedade profunda de profundidade desconhecida, eu vim com o abaixo sem a necessidade de percorrer todas as propriedades conhecidas de todas as crianças.

Por exemplo, para encontrar $ foo-> Bar-> baz, ou US $ foo-> baz, ou US $ foo-> Bar-> Baz-> dave, onde $ caminho é uma string 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};

}

E, em seguida, chamar com algo como:

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

Aqui é a minha tentativa. Ele tem algumas verificações comuns 'estupidez' embutido, certificando-se de que você não tentar definir ou obter um membro que não está disponível.

Você poderia passar cheques desses property_exists 'para __set e __get respectivamente, e chamá-los diretamente dentro mágica ().

<?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";

?>

O que esta função faz é que verifica se a exist propriedade sobre esta classe de qualquer um de seus criança, e se assim ele recebe o valor caso contrário ele retorna nulo. Então agora as propriedades são opcionais e dinâmica.

/**
 * 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 edit: antes: usando eval (mal) depois: no eval em tudo. ser velho nesta língua.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top