Как получить свойство в PHP на основе строки? Я назову его magic
. Итак, что такое magic
?
$obj->Name = 'something';
$get = $obj->Name;
будет выглядеть как...
magic($obj, 'Name', 'something');
$get = magic($obj, 'Name');
Как получить свойство в 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;
класс библиотеки, нуждающийся в источнике из другого класса, также с родительским экземпляром
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 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 вообще. будучи старыми на этом языке.