通过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。 在这个语言中老。