如何将数据库中的信息添加到现有的对象数组中?
How to add information from the DB to an existing array of objects?
我有一个格式如下的数组;
// echo '<pre>' . var_export($this->viewableFields, true) . '</pre>';
array (
0 =>
(object) array(
'formId' => '4',
'userId' => '7'
),
1 =>
(object) array(
'formId' => '4',
'userId' => '4'
)
)
我需要修改数据并向此数组添加另一个 key/value。我需要使用数组中的 userId
值,查询 MySQL 数据库和 return 值。我需要为每个数组元素执行此操作。
所以对于每个数组元素,我想 运行 一个查询,例如;
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';
});
我不确定如何从数据库中检索值并将其插入现有数组。
我怎样才能做到这一点?
您必须 foreach 项,从数组项中获取 ID,然后 select 数据 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
}
}
首先我们将从对象数组中获取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.
}
}
为每条记录做一个额外的查询是一个非常糟糕的主意,也是 N+1 问题的一个明显例子:你需要在哪里得到"N" 个实体的子实体,最初只获取了父实体。
如果您的初始查询有 100 个用户,您将结束进行 101 个查询。如果您以后需要一些其他不相关的领域,这将很快变得一发不可收拾。
这对性能非常不利,并且随着您的应用程序变得越来越复杂,它很容易对其产生非常严重的影响。
假设您无法修改初始查询并进行简单的 JOIN
查询来获取所需数据,最好进行两次查询并拼接结果数据。即使您可以修改原始查询,这最终可能会表现得更好。
怎么做:
假设您的初始对象数组具有 formId
和 userId
public 属性,首先获取您感兴趣的所有用户 ID:
$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";
现在这只是 "stiching" 来自两个查询的数据的问题:
foreach ($conn->query($groups_query) as $row) {
$index[$row['userId']]->group = $row['group'];
}
有了这个,现在包含 "user" 个对象的原始 $array
将得到正确更新,并且只进行 2 次查询而不是 11。这样可以更好地执行和扩展,并且不会显着增加复杂性。
您可以看到一个简单的工作演示(使用数组而不是 SQL 查询)here。
我有一个格式如下的数组;
// echo '<pre>' . var_export($this->viewableFields, true) . '</pre>';
array (
0 =>
(object) array(
'formId' => '4',
'userId' => '7'
),
1 =>
(object) array(
'formId' => '4',
'userId' => '4'
)
)
我需要修改数据并向此数组添加另一个 key/value。我需要使用数组中的 userId
值,查询 MySQL 数据库和 return 值。我需要为每个数组元素执行此操作。
所以对于每个数组元素,我想 运行 一个查询,例如;
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';
});
我不确定如何从数据库中检索值并将其插入现有数组。
我怎样才能做到这一点?
您必须 foreach 项,从数组项中获取 ID,然后 select 数据 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
}
}
首先我们将从对象数组中获取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.
}
}
为每条记录做一个额外的查询是一个非常糟糕的主意,也是 N+1 问题的一个明显例子:你需要在哪里得到"N" 个实体的子实体,最初只获取了父实体。
如果您的初始查询有 100 个用户,您将结束进行 101 个查询。如果您以后需要一些其他不相关的领域,这将很快变得一发不可收拾。
这对性能非常不利,并且随着您的应用程序变得越来越复杂,它很容易对其产生非常严重的影响。
假设您无法修改初始查询并进行简单的 JOIN
查询来获取所需数据,最好进行两次查询并拼接结果数据。即使您可以修改原始查询,这最终可能会表现得更好。
怎么做:
假设您的初始对象数组具有 formId
和 userId
public 属性,首先获取您感兴趣的所有用户 ID:
$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";
现在这只是 "stiching" 来自两个查询的数据的问题:
foreach ($conn->query($groups_query) as $row) {
$index[$row['userId']]->group = $row['group'];
}
有了这个,现在包含 "user" 个对象的原始 $array
将得到正确更新,并且只进行 2 次查询而不是 11。这样可以更好地执行和扩展,并且不会显着增加复杂性。
您可以看到一个简单的工作演示(使用数组而不是 SQL 查询)here。