Php algorithm - How to achieve that without eval
- by Marcelo
I have a class that keeps data stores/access data by using words.separated.by.dots keys and it behaves like the following:
$object = new MyArray()
$object->setParam('user.name','marcelo');
$object->setParam('user.email','[email protected]');
$object->getParams();
/*
array(
'user' => array(
'name' => 'marcelo',
'email' => '[email protected]'
)
);
*/
It is working, but the method unsetParam() was horribly implemented. That happened because i didn't know how to achieve that without eval() function. Although it is working, I found that it was a really challenging algorithm and that you might find fun trying to achieve that without eval().
class MyArray {
/**
* @param string $key
* @return Mura_Session_Abstract
*/
public function unsetParam($key)
{
$params = $this->getParams();
$tmp = $params;
$keys = explode('.', $key);
foreach ($keys as $key) {
if (!isset($tmp[$key])) {
return $this;
}
$tmp = $tmp[$key];
}
// bad code!
$eval = "unset(\$params['" . implode("']['", $keys) . "']);";
eval($eval);
$this->setParams($params);
return $this;
}
}
The test method:
public function testCanUnsetNestedParam()
{
$params = array(
'1' => array(
'1' => array(
'1' => array(
'1' => 'one',
'2' => 'two',
'3' => 'three',
),
'2' => array(
'1' => 'one',
'2' => 'two',
'3' => 'three',
),
)
),
'2' => 'something'
);
$session = $this->newSession();
$session->setParams($params);
unset($params['1']['1']['1']);
$session->unsetParam('1.1.1');
$this->assertEquals($params, $session->getParams());
$this->assertEquals($params['1']['1']['2'], $session->getParam('1.1.2'));
}