2012-12-31 61 views
4

我在这里有一个相当复杂的情况。我找不到一个更好的方法来解决这个问题,而不需要在进入该页面时将SELECT查询放入循环700多次的循环中(不用担心,我使用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_images表结构: imgit_images table schema

虽然这是imgit_users模式: imgit_users table schema

+2

您应该检查',其中X IN(...)' http://stackoverflow.com/questions/9736284/mysql-where-in – mbinette

+0

说实话,我想过,但然后我再也不知道如何在循环中使用带有user_ids的数组,然后获取用户名。我怎么知道哪个'image_name'适合'user_id'和两个不同的数组? – Aborted

+1

您可以在循环中选择'user_id'和'image_name',这样就可以获得两者之间的关联。 – mbinette

回答

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']; 
} 

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

+0

嘿。它有点作用,但我的逻辑仍然被阻止,我无法弄清楚如果循环中的image_name等于我们从查询中获得的image_name,那么如何检查主循环(我循环'scandir()')的内部,所以我们可以将用户名添加到该图像。这是一个例子,我创建的方法(基于你的查询)返回一个数组:'Array([user_id] => 4 [image_name] => 7E4c1i2.jpg [username] => DEATHMETALGORE)' – Aborted

+0

你是什么意思?如果'image_names'不等于,它不会在查询结果中结束!或者你的意思是说你想确保查询结果中的顺序与'$ images'中的顺序相同? – mbinette

+0

我得到它的工作。我将添加一个pastebin.com链接,以显示我是如何在第二秒完成的。非常感谢* mbinette *! – Aborted

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部分,但你可能会在这里使用连接),但它会在每次迭代时返回用户的信息,并且不需要进一步的迭代来获取用户的信息。

1

不知道这是否会帮助,但我看到一对夫妇的优化,有可能的:

  1. 准备外循环查询,反弹/执行/获取循环中产生。如果查询准备昂贵,则可能会节省相当多的时间。

  2. 您可以像Passing an array to a query using a WHERE clause那样传递数组并获取图像和用户标识,这样您可以将查询分割为更少数量的查询。