PHP: заполнение вложенного массива из плоских скалярных значений - PullRequest
2 голосов
/ 25 июня 2010

ПРОБЛЕМА

У меня есть вложенный массив PHP, который мне нужно заполнить из плоских скалярных значений.Проблема в том, что я не могу знать заранее, какова будет структура вложенного массива PHP, пока я не получу запрос на заполнение плоских скалярных значений.

ПРИМЕР

</p> <pre><code>// example where we populate the array using standard PHP $person['contact_info']['fname'] = 'Attilla'; $person['contact_info']['lname'] = 'Hun'; $person['contact_info']['middle'] = 'The'; $person['hobbies'][0] = 'Looting'; $person['hobbies'][1] = 'Pillaging'; // example where we populate the array from flat scalar values // (these are obtained from the user via name-value pairs) // how can I correctly populate $person from this?? print($_GET['contact_info.fname']); // 'Smokey'; print($_GET['contact_info.middle']); // 'The'; print($_GET['contact_info.lname']); // 'Bear'; // how can I correctly populate $person from this?? print($_GET['contact_info.fname']); // 'Jabba'; print($_GET['contact_info.middle']); // 'The'; print($_GET['contact_info.lname']); // 'Hutt'; // How can I use these three flat scalars // to populate the correct slots in the nested array?

ВОПРОС

Я знаю, что я не должен быть первым человеком, которому нужно было перейти от плоского имени-пары значений во вложенный массив PHP (или вложенный массив на любом языке программирования).Каков установленный способ (если таковой имеется) преобразования этих плоских скалярных пар имя-значение в соответствующий вложенный массив PHP?

Просто для повторения, я не могу знать заранее, что будут пары имя-значениебыть для заполнения массива, это одно ограничение, с которым я здесь имею дело.

ОБНОВЛЕНИЕ

Тот факт, что я не могу знать значения (или, если вы предпочитаете,ключи массива, которые заполняются представлениями скалярных значений), являются ограничением конкретного проблемного пространства, с которым я имею дело.Это не вопрос базового синтаксиса массива PHP.

Ответы [ 2 ]

0 голосов
/ 25 июня 2010

Примечание. Мой PHP-код, приведенный ниже, является хаком, вместо этого сделайте это. Кто-то ранее опубликовал более подходящее решение, но публикация исчезла. Одним словом, вы уже можете отправлять массивы значений в формах в PHP:

<form ...>
<input type="text" name="contact_info[fname]">
<input type="text" name="contact_info[lname]">
<input type="text" name="contact_info[middle]">
</form>

Квадратные скобки в атрибуте имени делают именно то, что, как вы думаете, они могут сделать. При отправке $_POST['contact_info'] будет массивом с тремя ключами: fname, lname и middle.

.

Если это вообще возможно, вам следует использовать этот метод, а не код, который я написал ниже. Это чище, лучше, удобнее в обслуживании, так и должно быть.


Это забавный вызов. Мы собираемся использовать забавный способ PHP сделать ссылки на наше преимущество. Учитывая, что:

  • $ input - это массив, который содержит только пары ключ / значение для $ person
  • Точка всегда является символом-разделителем
  • Вы никогда не встретите ключ, который имеет значения как массива, так и не массива, т. Е. Никогда не будет и 'contact_info', и 'contact_info.foo'

Тогда эта функция может стать для вас отправной точкой.

function nifty_splitty_magicky_goodness($input) {
// Start out with an empty array.
    $person = array();
    foreach($input as $k => $v) {
    // This turns 'a.b' into array('a', 'b')
        $key_parts = explode('.', $k);
    // Here's the magic.  PHP references aren't to values, but to
    // the variables that contain the values.  This lets us point at
    // array keys without a problem.  Sometimes this gets in the way...
        $ref = &$person;
        foreach($key_parts as $part) {
        // If we didn't already turn the thing we're refering to into an array, do so.
            if(!is_array($ref))
                $ref = array();
        // If the key doesn't exist in our reference, create it as an empty array
            if(!array_key_exists($part, $ref))
                $ref[$part] = array();
        // Reset the reference to our new array.
            $ref = &$ref[$part];
        }
    // Now that we're pointing deep into the nested array, we can
    // set the inner-most value to what it should be.
        $ref = $v;
    }
    return $person;
}

// Some test data.    
$input = array(
    'a.b' => 1,
    'a.c' => 2,
    'a.d.e' => 3,
    'f' => 4,
    'g.h' => 5
);
// Run it!
var_export(nifty_splitty_magicky_goodness($input));
// Should produce:
array (
  'a' => 
  array (
    'b' => 1,
    'c' => 2,
    'd' => 
    array (
      'e' => 3,
    ),
  ),
  'f' => 4,
  'g' => 
  array (
    'h' => 5,
  ),

Опять же, это хак. Вы должны использовать обработку форм PHP, чтобы позаботиться об этом за вас.

0 голосов
/ 25 июня 2010

Я не уверен, что вы имеете в виду, говоря, что вы не можете заранее знать, какими будут пары имя-значение.

В отношении вашего примера это будет работать:

<?php

$person['contact_info']['fname']  = $_GET['contact_info.fname'];
$person['contact_info']['lname']  = $_GET['contact_info.middle'];
$person['contact_info']['middle'] = $_GET['contact_info.lname']);    

?>

Не знать заранее значения - это данность - так обстоит дело с пользовательским вводом.

Вы должны знать клавиши заранее.Без этой информации вы не сможете узнать, как сопоставить значения в $_GET со значениями в $person.

Если вы заранее не знаете ключей, вы не сможете решить эту проблему.Если вы заранее не знаете ключей, существует серьезная ошибка в разработке программного обеспечения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...