嵌套对象方法从string调用

时间:2010-09-29 13:22:18

标签: php

如何在PHP中调用它:

$a = new Person();
$b = "method1()->method2()->method3()->methodn()";

$s->$b // doesn't work; 

我不想被“ - >”爆炸然后分别调用每个方法。

3 个答案:

答案 0 :(得分:2)

只要他们没有任何参数,你 COULD 就可以做到这一点(不是很强大,因为它可能很容易被错误的字符串打破。但你可以添加更多的错误检查如果你真的尝试过,支持参数......:

$methods = explode('->', $b);

$ref = &$a;
foreach ($methods as $method) {
    $method = preg_replace('#\\(.*?\\)#', '', $method);
    $ref = &$ref->$method();
}

但我同意NullUserException它通常表明设计不好......(我认为链接一般是设计糟糕的标志,但这只是我的个人意见)......

但不管怎样,它比eval更安全,所以如果你必须,你可能想尝试这样的事情......

编辑:根据您更新的答案(想要将函数映射到对象数组):

使用php 5.3:

$newArray = array_map(
    function($value) { 
        return $value->parent()->name;
    },
    $array
);

或者使用PHP< = 5.2:

$func = create_function('$value', 'return $value->parent()->name;');
$newArray = array_map($func, $array);

因此,您的最终map方法变为:

public function map($string) {
    $func = create_function('$value', 'return $value' . $string . ';');
    $return = array();
    foreach ($this as $key => $value) {
        $return[$key] = $func($value);
    }
}

由于它不是数组,array_map不会直接工作......但你可以遍历对象本身。

但要注意,这并不比eval更安全,所以你真的应该看一个不同的解决方案(比如映射一个回调):

public function map($callback) {
    $return = array();
    foreach ($this as $key => $value) {
        $return[$key] = $callback($value);
    }
}

用法:

$array = $collection->map(function($value) { return $value->parent()->name; });

答案 1 :(得分:0)

您可能需要检查“eval”:

eval('$a' . $b);

但要注意:除非你自己控制$b,否则你可能会因为不好的事情而打开自己。如果$b来自用户可以更改或泄漏更改的任何来源,这可能是一个主要的安全漏洞!

答案 2 :(得分:0)

我正在尝试像我自己的集合对象一样使用ruby map(在arrayobject上构建)。如果我有对象数组,我不会这样做:

$people->map('name') //which should return array of names

$people->map('parent()->name') //which should return array of names of parents