Получить свойство класса PHP по строке
как получить свойство в PHP на основе строки? Я назову это magic
. Так что же такое magic
?
$obj->Name = 'something';
$get = $obj->Name;
будет...
magic($obj, 'Name', 'something');
$get = magic($obj, 'Name');
12 ответов:
такой
<?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. В случае моего обстоятельства использование фигурной скобки также помогло...
пример с воспламенителем кода get instance
в исходном классе библиотеки называется что-то с родительским экземпляром класса
$this->someClass='something'; $this->someID=34;
класс библиотеки, из которого нужно исходить другой класс также с родительским экземпляром
echo $this->CI->{$this->someClass}->{$this->someID};
просто как дополнение: Таким образом, вы можете получить доступ к свойствам с именами, которые в противном случае были бы непригодны
$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) }(Не то, что вы должны, но в случае, если вы должны).
Если вы хотите сделать еще более причудливые вещи, вы должны посмотреть в отражение
там могут быть ответы на этот вопрос, но вы можете увидеть эти миграции в 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 (зло) после : без оценки вообще. быть старым на этом языке.