Получить свойство класса PHP по строке

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

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

будет, как…

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

Как это

 <?php $prop = 'Name'; echo $obj->$prop; 

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

 echo $obj['Name']; 

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

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

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

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

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

 $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 

Что-то вроде этого? Не проверял, но должен работать нормально.

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

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

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

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

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

пример с экземпляром Code Igniter get

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

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

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

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

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

  $ x = новый StdClass; 

$ prop = 'a b';
$ x -> $ prop = 1;
$ x -> {'x y'} = 2;
var_dump ($ х);

  object (stdClass) # 1 (2) {
   [ "AB"] =>
   INT (1)
   [ "Х"] =>
   Int (2)
 } 

(не то, что вам нужно, но в случае, если вам нужно).
Если вы хотите сделать даже более причудливый материал, вы должны заглянуть в размышления

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

отстающие несовместимые изменения

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

Вот моя попытка. У этого есть некоторые общие проверки «глупости», встроенные, убедившись, что вы не пытаетесь установить или получить член, который недоступен.

Вы можете перенести эти проверки property_exists на __set и __get соответственно и называть их непосредственно в 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"; ?> 

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

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

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

Например, чтобы найти $ 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); 
 $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); 

зачем редактировать: до: использование eval (зла) после: no eval вообще. будучи старым на этом языке.