按字符串获取PHP类属性

时间:2009-04-30 00:07:06

标签: php string oop properties

如何根据字符串获取PHP中的属性?我称之为magic。那么什么是magic

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

会像......

magic($obj, 'Name', 'something');
$get = magic($obj, 'Name');

12 个答案:

答案 0 :(得分:218)

喜欢这个

<?php

$prop = 'Name';

echo $obj->$prop;

或者,如果您可以控制该类,请实现ArrayAccess界面并执行此操作

echo $obj['Name'];

答案 1 :(得分:142)

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

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

这也允许您在循环中构建属性名称,例如:

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

答案 2 :(得分:10)

您所询问的内容称为Variable 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

答案 3 :(得分:7)

这样的东西?没有测试过,但应该可以正常工作。

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

答案 4 :(得分:5)

只需将属性名称存储在变量中,然后使用该变量访问该属性。像这样:

$name = 'Name';

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

答案 5 :(得分:3)

很简单,$ obj-&gt; {$ obj-&gt; Name}花括号将属性包装成变量变量。

这是一次热门搜索。但是没有解决我的问题,即使用$ this。在我的情况下使用花括号也有帮助...

使用Code Igniter获取实例

的示例 在具有父类实例

的名为something的源类库中的

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

库类需要使用父实例

从另一个类中获取源代码
echo $this->CI->{$this->someClass}->{$this->someID};

答案 6 :(得分:2)

同样是一个补充: 通过这种方式,您可以访问名称无法使用的属性

$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)
}
(不是您应该这样做,但如果必须的话)。
如果你想做更好的东西,你应该看看reflection

答案 7 :(得分:2)

这个问题可能有答案,但您可能希望看到这些迁移到PHP 7

backward incompatible change

来源:php.net

答案 8 :(得分:0)

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

您可以将这些'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";

?>

答案 9 :(得分:0)

这个函数的作用是检查该属性是否存在于他的任何一个孩子的这个类中,如果是,则获取该值,否则返回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);

答案 10 :(得分:0)

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

例如,要查找$ Foo-&gt; Bar-&gt; baz,或$ Foo-&gt; baz,或$ Foo-&gt; Bar-&gt; Baz-&gt; dave,其中$ path是一个类似的字符串&#39;富/酒吧/巴兹&#39;

Textview

然后拨打电话:

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};

}

答案 11 :(得分:-6)

$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(邪恶) 之后:根本没有评估。在这种语言中老了。