Get PHP class property by string

Jak uzyskać Właściwość w PHP opartą na łańcuchu znaków? Nazwę to magic. Czym więc jest magic?

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

Byłoby jak...

magic($obj, 'Name', 'something');
$get = magic($obj, 'Name');
Author: this.lau_, 2009-04-30

12 answers

Like this

<?php

$prop = 'Name';

echo $obj->$prop;

Lub, jeśli masz kontrolę nad klasą, zaimplementuj interfejs ArrayAccess i po prostu zrób to

echo $obj['Name'];
 201
Author: Peter Bailey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-17 01:57:24

Jeśli chcesz uzyskać dostęp do właściwości bez tworzenia zmiennej pośredniej, użyj notacji {}:

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

To również pozwala zbudować nazwę właściwości w pętli, na przykład:

for ($i = 0; $i < 5; $i++) {
    $something = $object->{'something' . $i};
    // ...
}
 130
Author: this.lau_,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-03 09:37:06

To, o co pytasz, nazywa się zmiennymi zmiennymi . Wszystko, co musisz zrobić, to zapisać swój łańcuch w zmiennej i uzyskać do niego dostęp w następujący sposób:

$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
 9
Author: matpie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-30 00:33:36

Coś takiego? Nie testowałem go, ale powinien działać dobrze.

function magic($obj, $var, $value = NULL)
{
    if($value == NULL)
    {
        return $obj->$var;
    }
    else
    {
        $obj->$var = $value;
    }
}
 7
Author: Ólafur Waage,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-30 00:13:47

Po prostu zapisz nazwę właściwości w zmiennej i użyj zmiennej, aby uzyskać dostęp do właściwości. Tak:

$name = 'Name';

$obj->$name = 'something';
$get = $obj->$name;
 5
Author: Jon Benedicto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-30 00:14:27

To proste, $obj - > {$obj - > Name} nawiasy klamrowe zawijają właściwość tak jak zmienna zmienna.

/ Align = "left" / Ale nie rozwiązał mojego pytania, które było za pomocą $this. W przypadku mojej sytuacji pomogło również użycie klamry kręconej...

Przykład z instancją Code Igniter get

W źródłowej klasie bibliotecznej o nazwie coś z macierzystą instancją klasy

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

Klasa biblioteczna musi pobierać z innej klasy również z instancja rodziców

echo $this->CI->{$this->someClass}->{$this->someID};
 3
Author: Mark Allen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-13 17:44:32

Tylko jako dodatek: W ten sposób można uzyskać dostęp do właściwości o nazwach, które w przeciwnym razie byłyby bezużyteczne

$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)
}
(nie to, że powinieneś, ale na wypadek, gdybyś musiał).
Jeśli chcesz robić jeszcze bardziej fantazyjne rzeczy, powinieneś zajrzeć do reflection
 2
Author: VolkerK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-30 00:22:41

Mogą być odpowiedzi na to pytanie, ale możesz chcieć zobaczyć te migracje do PHP 7

wsteczna niezgodna zmiana

Źródło: php.net

 2
Author: Muhammad Maulana,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-23 08:42:10

Oto moja próba. Ma wbudowane kilka typowych sprawdzeń "głupoty", upewniając się, że nie próbujesz ustawić lub uzyskać członka, który nie jest dostępny.

Można przenieść te kontrole 'property_exists' odpowiednio do _ _ set I _ _ get i wywołać je bezpośrednio w 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";

?>
 0
Author: Nick Presta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-30 00:32:15

To, co robi ta funkcja, to sprawdza, czy właściwość istnieje na tej klasie któregokolwiek z jego potomków, a jeśli tak, to otrzymuje wartość, w przeciwnym razie zwraca null. Więc teraz właściwości są opcjonalne i dynamiczne.

/**
 * 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;
}

Użycie:

const CONFIG_FILE_PATH_PROPERTY = 'configFilePath';

$configFilePath = $this->getIfExist(self::CONFIG_FILE_PATH_PROPERTY);
 0
Author: Mahmoud Zalt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-27 13:11:41

W przypadku, gdy ktoś jeszcze chce znaleźć głęboką właściwość nieznanej głębokości, wymyśliłem poniżej bez potrzeby przeglądania wszystkich znanych właściwości wszystkich dzieci.

Na przykład, aby znaleźć $Foo->Bar - > baz, lub $Foo - > baz, lub $Foo->Bar->Baz->dave, gdzie $path jest łańcuchem typu '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};

}

A następnie zadzwoń z czymś w rodzaju:

$propertyString = getXMLAttribute('string'); // '@Foo/Bar/baz'
$propertyString = substr($propertyString, 1);
$moduleCaller = new ModuleCaller();
echo $moduleCaller->callModule($propertyString);
 0
Author: Jordan Whitfield,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-15 14:07:12
$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);

Dlaczego edytować: przed: using eval (evil) po: brak ewaluacji. bycie Starym w tym języku.

 -7
Author: r4ccoon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-28 01:07:56