Как добавить информацию из БД в существующий массив объектов? - PullRequest
4 голосов
/ 09 марта 2020

У меня есть массив в следующем формате;

<code>// echo '<pre>' . var_export($this->viewableFields, true) . '
'; массив (0 => (объект) массив ('formId' => '4', 'userId' => '7'), 1 => (объект) массив ('formId' => '4', 'userId' = > '4'))

Мне нужно изменить данные и добавить еще один ключ / значение в этот массив. Мне нужно использовать значение userId из массива, запросить базу данных MySQL и вернуть значение. Мне нужно сделать это для каждого элемента массива.

Таким образом, для каждого элемента массива я хочу выполнить запрос вроде:

SELECT group from users WHERE userId = [userId in array]

Затем я хочу добавить это значение в массив, окончательный массив должен выглядеть так:

array (
  0 => 
  (object) array(
     'formId' => '4',
     'userId' => '7',
     'group' => 'Registered'
  ),
  1 => 
  (object) array(
     'formId' => '4',
     'userId' => '4',
     'group' => 'Admin'
  )
) 

Я знаю, что могу добавить дополнительное значение к элементам массива, используя array_walk, вот так;

array_walk($this->viewableFields, function(&$arr) {
    $arr->group = 'Registered';
});

Я не конечно, как получить значения из базы данных и вставить в существующий массив.

Как мне этого добиться?

Ответы [ 3 ]

4 голосов
/ 09 марта 2020

Выполнение одного дополнительного запроса для каждой записи - очень плохая идея и яркий пример проблемы N + 1 : где вам нужно получить «N» дочерних элементов сущности, и изначально была выбрана только родительская сущность .

Если у вашего исходного запроса 100 пользователей, вы закончите делать 101 запрос. Если позже вам понадобится какое-то другое несвязанное поле, оно начинает быстро выходить из-под контроля.

Это очень плохо для производительности , а поскольку ваше приложение усложняется, оно может очень легко иметь очень серьезное влияние на это.

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

Как go об этом:

Предполагая, что у вас есть исходный массив объектов с formId и userId publi c properties, сначала извлеките все интересующие вас идентификаторы пользователей:

$index = [];
$ids = array_reduce($array, function($ids, $object) use (&$index) {
    $ids[]                  = $object->userId;
    $index[$object->userId] = $object;

    return $ids;
});

$ids_for_sql = '(' . implode(', ', $ids) . ')';

Вы также создаете "index" ($index), чтобы иметь возможность доступа к объектам непосредственно в массив без необходимости повторять его снова.

Теперь вы можете сделать второй запрос, который вам нужен, чтобы получить свойство "group":

$groups_query = "SELECT userId, group from users WHERE userId IN $ids_for_sql";

Теперь это просто вопрос " сшивание "данных двух запросов:

foreach ($conn->query($groups_query) as $row) {
    $index[$row['userId']]->group = $row['group'];
}

. Теперь ваш исходный $array, содержащий" пользовательские "объекты, будет корректно обновлен, и выполнит только 2 запроса вместо 11 . Это работает и масштабируется лучше, без добавления существенной сложности.

Вы можете увидеть простую работающую демонстрацию (с массивами вместо SQL запросов) здесь .

1 голос
/ 09 марта 2020

Сначала мы получим значение userID из массива объектов, а затем запросим его в базе данных, приняв массив как $ arr.

foreach($arr AS $key=>$item) 
{
    $userid=$item["userId"];  // getting userId from object
    $query= $con->query("SELECT group from users WHERE userId='$userid'");
    if($query->num_rows>0)  //checking if query has some result
    {
        $row=$result->fetch_assoc();      //fetching the result
        $arr[$key]->group=$row['group'];  // lastly attaching group key to the arr.
    }
}
0 голосов
/ 09 марта 2020

Вы должны указать элементы, получить идентификатор из элемента массива, а затем выбрать данные с помощью SQL.

Попробуйте:

foreach($array as $key=>$item) {
    $sql = "SELECT group from users WHERE userId = ".$item["userId"];
    $result = $conn->query($sql);
    if ($result->num_rows > 0) {
        $db_data = $result->fetch_assoc();
        //do stuff with db data

        $array[$key]["group"] = $group; //insert group to this variable
    }
}
...