4

我这里的情况相当复杂。如果不将 SELECT 查询放在一个循环中,当我进入该页面时,我找不到更好的方法来解决这个问题(别担心,我使用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在进入循环之前获取那些 s 并在循环中使用它们?

这是来自的表结构imgit_imagesimgit_images 表架构

虽然这是 的架构imgit_usersimgit_users 表架构

4

4 回答 4

3

像这样的东西会起作用(我不确定是否可以准备WHERE IN查询,因为值的 # 是未知的......否则,请确保你 sanatize$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'];
}

你可能需要稍微调整一下(还没有测试过),但你似乎可以做到,所以我不担心!

于 2012-12-31T14:54:13.113 回答
1

不确定它是否会有所帮助,但我看到了一些可能的优化:

  1. 在循环外准备查询,在循环内反弹/执行/获取结果。如果查询准备很昂贵,您可能会节省很多时间。

  2. 您可以像使用 WHERE 子句将数组传递给查询中一样传递数组并获取图像和用户 ID,这样您就可以将查询分成较少数量的查询。

于 2012-12-31T14:49:26.937 回答
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

这显然不能避免循环的需要(您可能会使用字符串连接来构建INwhere 子句的一部分,但无论如何您可能会在这里使用连接)但它会在每次迭代时返回用户的信息和防止需要进一步迭代来获取用户的信息。

于 2012-12-31T14:48:46.063 回答
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']
}

创建一串逗号分隔?的 s 并将它们写入IN' 括号中。然后将图像数组传递给execute(). 轻松完成,现在您所有想要的数据都可以在单个查询的单个结果集中获得。(根据需要向查询的 SELECT 子句添加其他列。)

于 2019-06-22T12:56:26.623 回答