我试图在这样的类中获取dinamically数据:
Class foo
{
private $config=array();
public __construct(){
$this->config['site']['title'] = 'XXXXX';
$this->config['site']['favicon'] = 'XXXXX.ico';
$this->config['site']['keywords'] = array('page','cute','other');
$this->config['otherthing'] = 'value';
/**etc**/
}
public function set($name,$value)
{
$tmp = explode('.',$name);
/** i dont know what i can do here **/
}
public function get($name)
{
$tmp = explode('.',$name);
/** i dont know what i can do here **/
}
}
$thing = new foo;
$this->set('site.keywords',array('other','keywords'));//this change a data inside foo->config['site']['keywords']
echo $this->get('site.title'); // gets data inside foo->config['site']['title']
echo $this->get('otherthing'); // gets data inside foo->config['otherthing']
数组维度可以通过dinamically进行更改,我希望在foo-> gt中设置/检索数据:顺序调用数组:function(fist.second.third.four.etc)。
编辑:
我可以用爆炸创建一个函数,我探索了这个可能性,但如果我使用这样的函数:
function get($name)
{
$tmp = explode('.',$name);
if(isset($this->config[$tmp[0]][$tmp[1]]))
return $this->config[$tmp[0]][$tmp[1]];
return '';
}
当我需要在3维($ this-> config [one] [two] [tree])或一维($ this-> config [one])中获取数组值时,函数无法处理结果。 我想获得数组的N维。
我也试过这个解决方案: function nameToArray($ name) { $ tmp = explode('。',$ name); $ return ='';
foreach($tmp as $v)
{
$return .= "['{$v}']";
}
return 'config'.$return;
}
function set($name,$value)
{
$this->{$this->nameToArray} = $value;
}
$foo->set('site.favicon','something.ico');
但这不会编辑$ foo-> config中的数组,这会在$ this中创建一个名为literally config ['site'] ['favicon']的新值。
我不知道我是怎么做到的,我尝试了很多方法,但我不能得到具体的结果。 谢谢你的帮助。
答案 0 :(得分:1)
使用reference引用数组中最新的已知点,并按每一步更新它:
$ref = &$this->config;
$keys = explode('.', $name);
foreach ($keys as $idx => $key) {
if (!is_array($ref)) {
// reference does not refer to an array
// this is a problem as we still have at least one key to go
}
if (!array_key_exists($key, $ref)) {
// key does not exist
// reaction depends on the operation
}
// update reference
$ref = &$ref[$key];
}
if
分支取决于操作。以下是getter和setter的示例:
public function get($name) {
$ref = &$this->config;
$keys = explode('.', $name);
foreach ($keys as $idx => $key) {
if (!is_array($ref)) {
throw new Exception('key "'.implode('.', array_slice($keys, 0, $idx-1)).'" is not an array');
}
if (!array_key_exists($key, $ref)) {
throw new Exception('key "'.implode('.', array_slice($keys, 0, $idx)).'" does not exist');
}
$ref = &$ref[$key];
}
return $ref;
}
public function set($name, $value) {
$ref = &$this->config;
$keys = explode('.', $name);
foreach ($keys as $idx => $key) {
if (!is_array($ref)) {
throw new Exception('key "'.implode('.', array_slice($keys, 0, $idx)).'" is not an array but '.gettype($ref));
}
if (!array_key_exists($key, $ref)) {
$ref[$key] = array();
}
$ref = &$ref[$key];
}
$ref = $value;
}
答案 1 :(得分:1)
我有另一种基于eval的解决方案 我只是将字符串与括号
连接起来<?php
Class foo {
private $config=array();
function __construct(){
$this->config['site']['title'] = 'testing';
$this->config['site']['favicon'] = 'XXXXX.ico';
$this->config['site']['keywords'] = array('page','cute','other');
$this->config['otherthing'] = 'value';
/**etc**/
}
public function set($name,$value)
{
$tmp = explode('.',$name);
$array_levels = "['";
foreach($tmp as $key) {
$array_levels .= $key."']['";
}
$array_levels = substr($array_levels, 0, -2);
eval('$this->config'.$array_levels.' = $value;');
}
public function get($name)
{
$tmp = explode('.',$name);
$array_levels = "['";
foreach($tmp as $key) {
$array_levels .= $key."']['";
}
$array_levels = substr($array_levels, 0, -2);
eval('$value = $this->config'.$array_levels.';');
return $value;
}
}
$thing = new foo;
$thing->set('site.keywords',array('other','keywords'));
echo $thing->get('site.title');
答案 2 :(得分:0)
正如您所见here,函数explode
接受字符串并返回一个数组。所以这就是你需要做的事情:
public function set($name,$value)
{
$tmp = explode('.',$name); //$tmp will now contain an array, so if $name = 'site.keywords'
//$tmp[0] will contain 'site' and $tmp[1] = 'keywords'
//if you send 'otherthing' as $name, then $tmp[1] will have no value
if(isset($tmp[1])){
$this->config[$tmp[0]][$tmp[1]] = $value; // this is like saying $this-config['site']['keywords'] = $value
}
else{
$this->config[$tmp[0]] = $value;
}
}
对于获取:
public function get($name)
{
$tmp = explode('.',$name);
if(isset($tmp[1])){
return $this->config[$tmp[0]][$tmp[1]];
}
else{
return $this->config[$tmp[0]];
}
}