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');
È stato utile?

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

modifica incompatibile con le versioni precedenti

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top