通过string获取PHP类属性

如何根据string获取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']; 

如果要在不创build中间variables的情况下访问属性,请使用{}符号:

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

这也允许你在一个循环中build立属性名称,例如:

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

你在问什么叫做variablesvariables 。 所有你需要做的就是将你的string存储在一个variables中,像这样访问它:

 $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 

像这样的东西? 没有testing过,但应该正常工作。

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

只需将属性名称存储在一个variables中,并使用该variables来访问属性。 喜欢这个:

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

很简单,$ obj – > {$ obj-> Name}大括号将像variablesvariables一样包装属性。

这是一个顶级的search。 但没有解决我的问题,这是使用$这个。 在我的情况下使用大括号也帮助…

用Code Igniter获取实例的例子

在一个源类的库类中调用了父类的实例

 $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);

 对象(stdClass)#1(2){
   [ “AB”] =>
   INT(1)
   [ “XY”] =>
   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。 所以现在这些属性是可选的和dynamic的。

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

如果其他人想要find深度不明的深层属性,我就想出了下面的内容,而不需要遍历所有儿童的所有已知属性。

例如,要查找$ Foo-> Bar-> baz或$ Foo-> baz或$ Foo-> Bar-> Baz-> dave,其中$ path是一个string,如'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(邪恶)之后:根本没有eval。 在这个语言中老。