Получить свойство класса PHP по строке - PullRequest
124 голосов
/ 30 апреля 2009

Как мне получить свойство в PHP на основе строки? Я назову это magic. Так что же такое magic?

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

было бы как ...

magic($obj, 'Name', 'something');
$get = magic($obj, 'Name');

Ответы [ 12 ]

218 голосов
/ 30 апреля 2009

Как это

<?php

$prop = 'Name';

echo $obj->$prop;

Или, если у вас есть контроль над классом, реализуйте интерфейс ArrayAccess и просто сделайте это

echo $obj['Name'];
142 голосов
/ 09 августа 2012

Если вы хотите получить доступ к свойству без создания промежуточной переменной, используйте запись {}:

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

Это также позволяет вам создать имя свойства в цикле, например:

for ($i = 0; $i < 5; $i++) {
    $something = $object->{'something' . $i};
    // ...
}
10 голосов
/ 30 апреля 2009

То, о чем вы спрашиваете, называется Переменные . Все, что вам нужно сделать, это сохранить вашу строку в переменной и получить к ней доступ так:

$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
7 голосов
/ 30 апреля 2009

Как то так? Не проверял, но должен нормально работать.

function magic($obj, $var, $value = NULL)
{
    if($value == NULL)
    {
        return $obj->$var;
    }
    else
    {
        $obj->$var = $value;
    }
}
5 голосов
/ 30 апреля 2009

Просто сохраните имя свойства в переменной и используйте переменную для доступа к свойству. Как это:

$name = 'Name';

$obj->$name = 'something';
$get = $obj->$name;
3 голосов
/ 23 ноября 2016

На этот вопрос могут быть ответы, но вы можете захотеть увидеть эти миграции на PHP 7

backward incompatible change

источник: php.net

3 голосов
/ 13 февраля 2012

Это просто, $ obj -> {$ obj-> Name} фигурные скобки обернут свойство так же, как переменная переменная.

Это был лучший поиск. Но не решил мой вопрос, который использовал $ this. В случае моих обстоятельств использование фигурной скобки также помогло ...

пример с Code Igniter get instance

в классе с источником из библиотеки, вызываемом с экземпляром родительского класса

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

класс библиотеки, необходимый для получения из другого класса, также с экземпляром родителя

echo $this->CI->{$this->someClass}->{$this->someID};
2 голосов
/ 30 апреля 2009

Так же, как дополнение: Таким образом, вы можете получить доступ к свойствам с именами, которые иначе были бы непригодны для использования

$x = new StdClass;</p>

<p>$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)
}
(не то, что вы должны, но в случае необходимости).
Если вы хотите делать еще более интересные вещи, вам стоит взглянуть на отражение
1 голос
/ 15 января 2017

В случае, если кто-то еще захочет найти глубокое свойство неизвестной глубины, я придумал нижеприведенное без необходимости перебирать все известные свойства всех детей.

Например, чтобы найти $ Foo-> Bar-> baz, или $ Foo-> baz, или $ Foo-> Bar-> Baz-> dave, где $ path представляет собой строку типа '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};

}

А затем позвоните с чем-то вроде:

$propertyString = getXMLAttribute('string'); // '@Foo/Bar/baz'
$propertyString = substr($propertyString, 1);
$moduleCaller = new ModuleCaller();
echo $moduleCaller->callModule($propertyString);
0 голосов
/ 27 мая 2015

Эта функция выполняет проверку того, существует ли свойство в этом классе какого-либо из его дочерних элементов, и если да, то получает значение, в противном случае возвращает нуль. Так что теперь свойства являются необязательными и динамическими.

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

Использование:

const CONFIG_FILE_PATH_PROPERTY = 'configFilePath';

$configFilePath = $this->getIfExist(self::CONFIG_FILE_PATH_PROPERTY);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...