我必须在PHP中实现一个 setter ,它允许我指定数组(目标)的键或子键,并将名称作为点分隔键值传递。
给出以下代码:
$arr = array('a' => 1, 'b' => array( 'y' => 2, 'x' => array('z' => 5, 'w' => 'abc') ), 'c' => null); $key = 'b.x.z'; $path = explode('.', $key);
从价值$key我想达到的值 5 的$arr['b']['x']['z']。
$key
$arr['b']['x']['z']
现在,给定变量值$key和不同的$arr值(深度不同)。
$arr
对于 getter, get()我编写了以下代码:
get()
public static function get($name, $default = null) { $setting_path = explode('.', $name); $val = $this->settings; foreach ($setting_path as $key) { if(array_key_exists($key, $val)) { $val = $val[$key]; } else { $val = $default; break; } } return $val; }
写一个 setter 比较困难,因为我成功地从到达了正确的元素$key,但是我无法在原始数组中设置值,而且我也不知道如何一次全部指定键。
我应该使用某种回溯吗?还是可以避免?
假设$path通过explode(或添加到函数)已经是一个数组,则可以使用引用。您需要添加一些错误检查以防无效$path等(请考虑isset):
$path
explode
isset
$key = 'b.x.z'; $path = explode('.', $key);
function get($path, $array) { //$path = explode('.', $path); //if needed $temp =& $array; foreach($path as $key) { $temp =& $temp[$key]; } return $temp; } $value = get($path, $arr); //returns NULL if the path doesn't exist
如果您传递的数组尚未定义,则此组合将在现有数组中设置一个值或创建该数组。确保定义$array要通过引用传递&$array:
$array
&$array
function set($path, &$array=array(), $value=null) { //$path = explode('.', $path); //if needed $temp =& $array; foreach($path as $key) { $temp =& $temp[$key]; } $temp = $value; } set($path, $arr); //or set($path, $arr, 'some value');
这将unset是路径中的最终键:
unset
function unsetter($path, &$array) { //$path = explode('.', $path); //if needed $temp =& $array; foreach($path as $key) { if(!is_array($temp[$key])) { unset($temp[$key]); } else { $temp =& $temp[$key]; } } } unsetter($path, $arr);
*原始答案的功能有限,以防某些人使用它们:
塞特犬
确保定义$array要通过引用传递&$array:
function set(&$array, $path, $value) { //$path = explode('.', $path); //if needed $temp =& $array; foreach($path as $key) { $temp =& $temp[$key]; } $temp = $value; } set($arr, $path, 'some value');
或者,如果您想返回更新的数组(因为感到无聊):
function set($array, $path, $value) { //$path = explode('.', $path); //if needed $temp =& $array; foreach($path as $key) { $temp =& $temp[$key]; } $temp = $value; return $array; } $arr = set($arr, $path, 'some value');
创作者
如果您不想创建数组并选择设置值:
function create($path, $value=null) { //$path = explode('.', $path); //if needed foreach(array_reverse($path) as $key) { $value = array($key => $value); } return $value; } $arr = create($path); //or $arr = create($path, 'some value');
为了娱乐
构造和计算类似于$array['b']['x']['z']给定字符串的内容b.x.z:
$array['b']['x']['z']
b.x.z
function get($array, $path) { //$path = explode('.', $path); //if needed $path = "['" . implode("']['", $path) . "']"; eval("\$result = \$array{$path};"); return $result; }
设置类似$array['b']['x']['z'] = 'some value';:
$array['b']['x']['z'] = 'some value';
function set(&$array, $path, $value) { //$path = explode('.', $path); //if needed $path = "['" . implode("']['", $path) . "']"; eval("\$array{$path} = $value;"); }
取消类似的设置$array['b']['x']['z']:
function unsetter(&$array, $path) { //$path = explode('.', $path); //if needed $path = "['" . implode("']['", $path) . "']"; eval("unset(\$array{$path});"); }