我的情况非常复杂。我没有找到一种更好的方法来解决这个问题,而不是在我进入该页面时将一个SELECT查询放入一个滚动超过70000次的循环中(不用担心,我使用array_chunk
将数组拆分成页面)。我想如果我在这里使用查询,这将是一个资源杀手。因此,我在这里问一个问题。
我需要循环使用这个大数组:
$images = scandir($imgit_root_path . '/' . IMAGES_PATH);
$indexhtm = array_search('index.htm', $images);
unset($images[0], $images[1], $images[$indexhtm]);
现在,我的IMAGES_PATH
中有一个包含文件(图像)的所有文件名的数组。现在问题来了:
其中一些图像已在数据库中注册,因为注册用户的图像列在我的数据库中。现在我需要根据上面的数组给我的图像名称检索user_id
。
在循环中我只是这样做:
foreach ($images as $image_name)
{
$query = $db->prepare('SELECT user_id FROM imgit_images WHERE image_name = :name');
$query->bindValue(':name', $image_name, PDO::PARAM_STR);
$query->execute();
$row = $query->fetch(PDO::FETCH_ASSOC);
$user_id = $row['user_id'];
echo $user_id;
}
这很好用,但效率等于0.使用user_id
我计划从imgit_users
表中获取其他内容,例如username
,这需要另一个查询在那个循环中。
这太多了,我需要一种更简单的方法来解决这个问题。
有没有办法在进入循环之前获取那些user_id
并在循环中使用它们?
这是imgit_images
的表格结构:
虽然这是imgit_users
的架构:
答案 0 :(得分:3)
这样的事情会起作用(我不确定是否可以准备WHERE IN
查询,因为价值的数量是未知的......否则,确保你对$images
进行整理强>):
$image_names = "'".implode("', '", $images)."'";
$query = $db->prepare("SELECT img.user_id, image_name, username
FROM imgit_images img
INNER JOIN imgit_users u ON u.user_id = img.user_id
WHERE image_name IN(".$image_names.")");
$query->execute();
while($row = $query->fetch(PDO::FETCH_ASSOC))
{
echo $row['user_id']."'s image is ".$row['image_name'];
}
您可能需要稍微调整一下(尚未测试过),但您似乎能够这样做,所以我并不担心!
答案 1 :(得分:1)
您是否可以在查询中使用INNER JOIN
,这样循环的每次迭代都会返回相应用户的详细信息。将您的查询更改为类似的内容(我在这里对表的结构做出假设):
SELECT imgit_users.user_id
,imgit_users.username
,imgit_users.other_column_and_so_on
FROM imgit_images
INNER JOIN imgit_users ON imgit_users.user_id = imgit_images.user_id
WHERE imgit_images.image_name = :name
这显然不能避免需要一个循环(你可能会使用字符串连接来构建你的where子句的IN
部分,但你可能在这里使用了一个连接)但它会返回每次迭代的用户信息,并防止需要进一步迭代来获取用户的信息。
答案 2 :(得分:1)
不确定它是否会有所帮助,但我看到了一些可能的优化:
在循环外准备查询,并在循环内反弹/执行/获取结果。如果查询准备工作很昂贵,您可能会节省相当多的时间。
您可以像Passing an array to a query using a WHERE clause一样传递数组并获取图片和用户ID,这样您就可以将查询分段为少量查询。
答案 3 :(得分:0)
PDO使您可以安全地编写查询。
$placeholders = implode(',', array_fill(0, count($images), '?'));
$sql = "SELECT u.username
FROM imgit_images i
INNER JOIN imgit_users u ON i.user_id = u.id
WHERE i.image_name IN ({$placeholders})";
$stmt = $db->prepare($sql);
$stmt->execute($images);
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
// use $row['username']
}
创建由逗号分隔的?
组成的字符串,并将其写入IN
的括号中。然后将图像数组传递到execute()
。轻松完成,现在您可以从单个查询的单个结果集中获得所有所需数据。 (根据需要将其他列添加到查询的SELECT子句中。)