Get PHP class property by string
如何在基于字符串的PHP中获取属性? 我将其称为
1 2 | $obj->Name = 'something'; $get = $obj->Name; |
就像...
1 2 | magic($obj, 'Name', 'something'); $get = magic($obj, 'Name'); |
像这样
1 2 3 4 5 | <?php $prop = 'Name'; echo $obj->$prop; |
或者,如果您可以控制该类,请实现ArrayAccess接口,然后执行此操作
1 | echo $obj['Name']; |
如果要访问属性而不创建中间变量,请使用
1 | $something = $object->{'something'}; |
这还允许您例如在循环中构建属性名称:
1 2 3 4 | for ($i = 0; $i < 5; $i++) { $something = $object->{'something' . $i}; // ... } |
您要问的是所谓的变量变量。您需要做的就是将字符串存储在变量中,然后像这样访问它:
1 2 3 4 5 6 7 8 9 | $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 |
像这样吗尚未测试,但应该可以正常工作。
1 2 3 4 5 6 7 8 9 10 11 | function magic($obj, $var, $value = NULL) { if($value == NULL) { return $obj->$var; } else { $obj->$var = $value; } } |
可能会有这个问题的答案,但您可能想看看这些向PHP 7的迁移
资料来源:php.net
只需将属性名称存储在变量中,然后使用该变量访问属性。像这样:
1 2 3 4 | $name = 'Name'; $obj->$name = 'something'; $get = $obj->$name; |
很简单,$ obj-> {$ obj-> Name}的大括号将把属性包装起来就像一个变量变量。
这是一个热门搜索。但是并没有解决我的问题,那就是使用$ this。在我的情况下,使用大括号也有帮助...
Code Igniter的示例获取实例
在带有父类实例的称为某些东西的源库类中
1 2 | $this->someClass='something'; $this->someID=34; |
需要与父实例一起从另一个类中获取资源的库类
1 | echo $this->CI->{$this->someClass}->{$this->someID}; |
作为补充:
这样,您可以使用名称否则将无法使用的属性访问属性
1 2 3 4 5 6 7 8 |
1 2 3 4 5 6 | object(stdClass)#1 (2) { ["a b"]=> int(1) ["x y"]=> int(2) } |
(不是您应该的,但是如果必须的话)。
如果您想做更奇特的事情,您应该考虑一下
万一其他人想找到未知深度的深层属性,我想出了以下内容,而无需遍历所有子级的所有已知属性。
例如,要查找$ Foo-> Bar-> baz或$ Foo-> baz或$ Foo-> Bar-> Baz-> dave,其中$ path是类似于'foo / bar / baz'的字符串。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 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}; } |
然后调用类似:
1 2 3 4 | $propertyString = getXMLAttribute('string'); // '@Foo/Bar/baz' $propertyString = substr($propertyString, 1); $moduleCaller = new ModuleCaller(); echo $moduleCaller->callModule($propertyString); |
该函数的作用是检查该属性是否存在于其任何子级的此类中,如果存在,则获取该值,否则返回null。
因此,现在这些属性是可选的并且是动态的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /** * 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; } |
用法:
1 2 3 | const CONFIG_FILE_PATH_PROPERTY = 'configFilePath'; $configFilePath = $this->getIfExist(self::CONFIG_FILE_PATH_PROPERTY); |
这是我的尝试。它内置了一些常见的"愚蠢"检查,以确保您不会尝试设置或获取不可用的成员。
您可以将那些" property_exists"检查分别移到__set和__get,然后直接在magic()中调用它们。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | <?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") ,"\ "; // error $f->magic("Fame","Something"); echo $f->magic("Fame") ,"\ "; ?> |
1 2 3 4 5 6 7 8 | $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(evil)
之后:完全没有评估。用这种语言老了。