2011-06-20 30 views
5

Nếu tôi có một mảng tương ứng với các khóa đệ quy liên tiếp trong một mảng khác, cách tốt nhất để gán giá trị cho "đường dẫn" đó (nếu bạn muốn gọi nó là gì)?Gán một chỉ mục mảng sâu tùy ý?

Ví dụ:

$some_array = array(); 
$path = array('a','b','c'); 
set_value($some_array,$path,'some value'); 

Bây giờ, $some_array phải bằng

array(
    'a' => array(
    'b' => array(
     'c' => 'some value' 
))) 

Tại thời điểm này, tôi đang sử dụng như sau:

function set_value(&$dest,$path,$value) { 
    $addr = "\$dest['" . implode("']['", $path) . "']"; 
    eval("$addr = \$value;"); 
} 

Rõ ràng, đây là một rất ngây thơ tiếp cận và đặt ra một nguy cơ bảo mật, vậy làm thế nào bạn sẽ làm điều đó?

+1

Điều gì xảy ra nếu đường dẫn không hợp lệ? – Matthew

+0

@konforce - Nó sẽ chỉ định anyways, như trong ví dụ trên của tôi khi '$ some_example' bắt đầu trống. –

+0

Tôi đã cập nhật câu trả lời của mình để phản ánh điều đó. Lưu ý nó bây giờ cũng ghi đè các giá trị chuỗi với mảng, nhưng điều đó sẽ đơn giản thay đổi nếu hành vi đó không được mong muốn. – Matthew

Trả lời

2

giải pháp đệ quy (không kiểm tra):

function set_value(&$dest,$path,$value) { 
     $index=array_shift($path); 
     if(empty($path)){ 
     // on last level 
     $dest[$index]=$value; 
     } 
     else{ 
     // descending to next level 
     set_value($dest[$index],$path,$value); 
     } 
    } 
2

Wow, nhắc nhở tôi về Lisp.

Yea, eval thường không phải là ý tưởng hay nhất.

Cá nhân, tôi sẽ chỉ đơn giản lặp:

function set_value(&$dest,$path,$value) { 
    $val =& $dest; 
    for($i = 0; $i > count($path) - 1; $i++) { 
    $val =& $val[$i]; 
    } 

    $val[$path[$i]] = $value; 
} 

Nếu bạn đang ở trong PHP 5 có lẽ bạn có thể nhận được thứ của một số trong những '&' quá

+1

Bạn có nghĩa là '$ val [$ path [$ i]]' nơi bạn có '$ val [$ i]'? – Matthew

+0

Ồ! Khá chính xác. Tôi đã sưa nó. Cảm ơn bạn. – cwallenpoole

2
function set_value(&$dest, $path, $value) 
{ 
    # allow for string paths of a/b/c 
    if (!is_array($path)) $path = explode('/', $path); 

    $a = &$dest; 
    foreach ($path as $p) 
    { 
    if (!is_array($a)) $a = array(); 
    $a = &$a[$p]; 
    } 

    return $a = $value; 
} 


set_value($a, 'a/b/c', 'foo'); 

cập nhật để làm việc với các phím chưa tồn tại và chấp nhận một mảng hoặc đường dẫn chuỗi.

2
function set_value(&$dest, $path, $value) { 
    $dest = array(array_pop($path) => $value); 
    for($i = count($path) - 1; $i >= 0; $i--) { 
     $dest = array($path[$i] => $dest); 
    } 
} 
Các vấn đề liên quan