2013-03-27 5 views
0

у меня есть проблема с следующий фрагмент кода:PHP OOP проблема с динамическими многомерными массивами

<?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

Я не знаю, почему это не работает! ! Если кто-то может пролить свет, это было бы весьма признательно.

Благодаря

ответ

2

Ну, вы не имеете свойство под названием «settings['paths']['protocol']». У вас есть свойство settings, у которого есть ключ paths, у которого есть ключ . Но PHP не интерпретирует $this->{$string} как код копирования и вставки кода, он ищет свойство «settings['paths']['protocol']», которого не существует. Это ничего особенного для кода ООП, как работает любая переменная переменная.


Я хотел бы предложить что-то вроде этого, вместо:

/** 
* 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 
    ); 
} 
+0

Знаете ли вы об ошибках в этом вопросе? Спасибо за объяснение, я понимаю проблему сейчас! –

+0

Что именно вы хотите сделать? Пример кода вряд ли имеет смысл, так как вы на самом деле не используете его так, я полагаю. – deceze

+0

Ну, см. Обновление. – deceze

Смежные вопросы