通过字符串获取 PHP 类属性

如何基于字符串获取 PHP 中的属性?我叫它 magicmagic是什么?

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

就像..。

magic($obj, 'Name', 'something');
$get = magic($obj, 'Name');
149020 次浏览

像这样

<?php


$prop = 'Name';


echo $obj->$prop;

或者,如果您可以控制这个类,那么就实现 ArrayAccess接口,然后这样做

echo $obj['Name'];

像这样的东西? 还没有测试,但应该可以工作。

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

只需将属性名存储在一个变量中,然后使用该变量访问该属性,如下所示:

$name = 'Name';


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

你要问的是 变量。您所需要做的就是将字符串存储在一个变量中,并像下面这样访问它:

$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

作为补充: 通过这种方式,您可以访问具有在其他情况下无法使用的名称的属性

$prop = ‘ a b’; $x-> $螺旋桨 = 1; $x-> {‘ x y’} = 2; Var _ dump ($x) ; < pre > object (stdClass) # 1(2){ [“ a b”] = > Int (1) [“ x y”] = > Int (2) } (不是说您应该这样做,而是以防万一)。 < br > 如果你想做一些更花哨的事情,你应该查看一下反射

$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) 完全没有评估。在这种语言中老了。

这是我的尝试。它内置了一些常见的“愚蠢”检查,以确保您不会尝试设置或获取不可用的成员。

您可以将这些“ property _ vis”检查分别移动到 _ _ 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";


?>

很简单,$obj-> { $obj-> Name }花括号将像变量变量一样包装属性。

这是最高搜索。但没有解决我的问题,这是使用 $this。在我的情况下,使用花括号也有所帮助..。

使用代码点火器获取实例

在源库类中调用具有父类实例的内容

$this->someClass='something';
$this->someID=34;

需要从另一个类源代码的库类也具有父实例

echo $this->CI->{$this->someClass}->{$this->someID};

如果希望在不创建中间变量的情况下访问该属性,请使用 {}表示法:

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

这还允许您在循环中生成属性名,例如:

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

这个函数的作用是检查这个属性是否存在于这个类的任何子类中,如果存在,它就会得到值,否则返回 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);

这个问题可能有答案,但是您可能希望看到这些向 PHP7的迁移

backward incompatible change

来源: Php.net

如果其他人想要找到一个深度未知的属性,我想出了下面的内容,而不需要遍历所有孩子的所有已知属性。

例如,要查找 $foo->Bar->baz->bam,给定一个对象($foo)和一个类似“ Bar-> baz-> bam”的字符串。

trait PropertyGetter {
public function getProperty($pathString, $delimiter = '->') {


//split the string into an array
$pathArray = explode($delimiter, $pathString);


//get the first and last of the array
$first = array_shift($pathArray);
$last = array_pop($pathArray);


//if the array is now empty, we can access simply without a loop
if(count($pathArray) == 0){
return $this->{$first}->{$last};
}


//we need to go deeper
//$tmp = $this->Foo
$tmp = $this->{$first};


foreach($pathArray as $deeper) {
//re-assign $tmp to be the next level of the object
// $tmp = $Foo->Bar --- then $tmp = $tmp->baz
$tmp = $tmp->{$deeper};
}


//now we are at the level we need to be and can access the property
return $tmp->{$last};


}
}

然后打电话说:

$foo = new SomeClass(); // this class imports PropertyGetter trait
echo $foo->getProperty("bar->baz->bam");