У меня есть класс, который хранит значения с многоуровневым ассоциативным массивом:
Мне нужно добавить способ доступа и изменения вложенных значений. Вот рабочее решение моей проблемы, но оно довольно медленное . Есть ли лучший способ сделать это ?
Примечание: использование функций get / set не обязательно, но должен быть эффективный способ определения значения по умолчанию.
class Demo {
protected $_values = array();
function __construct(array $values) {
$this->_values = $values;
}
public function get($name, $default = null) {
$token = strtok($name, '.#');
$node = $this->_values;
while ($token !== false) {
if (!isset($node[$token]))
return $default;
$node = $node[$token];
$token = strtok('.#');
}
return $node;
}
public function set($name, $value) {
$next_token = strtok($name, '.#');
$node = &$this->_values;
while ($next_token !== false) {
$token = $next_token;
$next_token = strtok('.#');
if ($next_token === false) {
$node[ $token ] = $value;
break;
}
else if (!isset($node[ $token ]))
$node[ $token ] = array();
$node = &$node[ $token ];
}
unset($node);
}
}
Который будет использоваться следующим образом:
$test = new Demo(array(
'simple' => 27,
'general' => array(
0 => array(
'something' => 'Hello World!',
'message' => 'Another message',
'special' => array(
'number' => 27
)
),
1 => array(
'something' => 'Hello World! #2',
'message' => 'Another message #2'
),
)
));
$simple = $test->get('simple'); // === 27
$general_0_something = $test->get('general#0.something'); // === 'Hello World!'
$general_0_special_number = $test->get('general#0.special.number'); === 27
Примечание: 'general.0.something' - это то же самое, что 'general # 0.something', альтернатива пунктуация сделана для ясности.