0

我对以下代码有疑问:

<?php
    class testClass
    {
        public $settings;

        public function __construct()
        {
            $this->settings = array(
                'paths' => array(
                    'protocol' => 'http'
                )
            );
        }

        public function getSomething()
        {
            $string = "settings['paths']['protocol']";

            echo $this->{$string};      /***** Line 19 *****/
        }
    }


    $obj = new testClass;
    $obj->getSomething();                          // Outputs a 'undefined' notice
    echo '<br />';
    echo $obj->settings['paths']['protocol'];      // Outputs http as expected
?>

这是我正在使用的代码的一个非常基本的示例,实际代码更高级,但产生的输出/错误是相同的。

基本上,类构造函数使用设置数组填充属性。getSomething() 方法将数组路径分配给变量,然后尝试由echo $this->{$string};代码检索该变量。

当我写时:$obj->getSomething();我收到以下错误:

Notice: Undefined property: testClass::$settings['paths']['protocol'] in /test.php on line 19

如果我编写以下代码echo $obj->settings['paths']['protocol'],我会得到预期的http

我不确定为什么这不起作用!如果有人能提供任何启示,将不胜感激。

谢谢

4

1 回答 1

2

好吧,你没有一个名为 " settings['paths']['protocol']" 的属性。您有一个名为settingswhich has key的属性,该属性paths具有 key protocol。但是 PHP$this->{$string}不像复制和粘贴代码那样解释,它会寻找一个名为 " settings['paths']['protocol']" 的属性,但它并不存在。这对 OOP 代码没什么特别的,它是任何变量变量的工作方式。


我会建议这样的东西:

/**
 * Get settings, optionally filtered by path.
 *
 * @param string $path A path to a nested setting to be returned directly.
 * @return mixed The requested setting, or all settings if $path is null,
 *               or null if the path doesn't exist.
 */
public function get($path = null) {
    $value = $this->settings;

    foreach (array_filter(explode('.', $path)) as $key) {
        if (!is_array($value) || !isset($value[$key])) {
            return null;
        }
        $value = $value[$key];
    }

    return $value;
}

像这样调用:

$obj->get('paths.protocol');

只是为了好玩,这里是上述的功能实现:;-3

public function get($path = null) {
    return array_reduce(
        array_filter(explode('.', $path)),
        function ($value, $key) { return is_array($value) && isset($value[$key]) ? $value[$key] : null; },
        $this->settings
    );
}
于 2013-03-27T13:12:18.997 回答