【问题标题】:Moving foreach loop inside the while loop is not working in the expected way [duplicate]在while循环内移动foreach循环没有以预期的方式工作[重复]
【发布时间】:2022-04-04 05:10:52
【问题描述】:

我需要一些帮助和说明如何正确完成这一切,因为看起来我做错了而且不是最佳方式,所以它浪费了我的服务器资源。

这是我的代码,它有效,但我认为如果将 foreach 放在 while 循环内,而不是像这样包装它,它可以优化以获得更快的性能:

$link_id = explode(',', $ref_links_id);
    foreach($link_id as $key => $value){
        $additional_links_query = 'SELECT * FROM additional_links WHERE id = '.$value.' ORDER BY ID asc';
        $res = $db->prepare($additional_links_query);
        $res->execute();
        while ($info = $res -> fetch()){
            $li_text = ($info['_ad_text'] == NULL)? '' : ' - '.$info['_ad_text'];
            $li_target = ($info['_ad_url_target'] == NULL)? '' : ' target="'.$info['_ad_url_target'].'"' ;
            $li_nofollow = ($info['_ad_nofollow'] == 1)? ' rel="nofollow"' : '';
            $li_cont = '<li><a href="'.$info['_ad_url'].'"'.$li_target.$li_nofollow.'>'.$info['_ad_anchor'].'</a>'.$li_text.'</li>';
        print<<<END
        $li_cont\n
        END;
    }
}

我最初的方法是将foreach 循环放在while 循环内,这样可以节省回合,但我的每一次尝试都失败了。

【问题讨论】:

    标签: php foreach while-loop


    【解决方案1】:

    如果我理解正确,您需要从代码中删除 foreachwhile 循环之一

    查看我从 PHP 中删除 foreach 并将 IN 命令添加到您的 SQL 查询的代码:

    $additional_links_query = 'SELECT * FROM additional_links WHERE id IN ('.implode(",", $ref_links_id).') ORDER BY ID asc';
    $res = $db->prepare($additional_links_query);
    $res->execute();
    while ($info = $res -> fetch()){
        $li_text = ($info['_ad_text'] == NULL)? '' : ' - '.$info['_ad_text'];
        $li_target = ($info['_ad_url_target'] == NULL)? '' : ' target="'.$info['_ad_url_target'].'"' ;
        $li_nofollow = ($info['_ad_nofollow'] == 1)? ' rel="nofollow"' : '';
        $li_cont = '<li><a href="'.$info['_ad_url'].'"'.$li_target.$li_nofollow.'>'.$info['_ad_anchor'].'</a>'.$li_text.'</li>';
    print<<<END
    $li_cont\n
    END;
    

    【讨论】:

    • 问题是 $ref_links_id 是一个数组,它不会像那样工作。我真正需要的是在 while 循环中移动 foreach 而不是在 forach 循环中移动。
    • 好吧,我把$ref_links_id改成implode(",", $ref_links_id)
    • IN() 需要 () 在值列表周围。另请注意,如果值是字符串,这将失败,'A,B,C' 将需要 FIND_IN_SET(id, 'A,B,C')
    • @AlexB 不会收到您的问题的通知,除非您在评论中使用@AlexB 通知。
    【解决方案2】:

    看起来您可以在单个查询中执行此操作,以及使用Prepared Statements 正确使用 MySQLI:

    $ref_links_arr = explode(',', $ref_links_id);
    
    // We need a series of parameter placeholders, e.g., ?,?,?
    // One for each ref_link_id, which will be used in the
    // query as placeholders in the IN() clause list.
    $ref_links_params = implode(',', array_fill(0, count($ref_links_arr ), '?'));
    
    // Using IN(), see the links below for the MySQL manual entry.
    $additional_links_query = "
    SELECT * 
    FROM additional_links 
    WHERE id IN($ref_links_params) 
    ORDER BY ID asc
    ";
    
    $res = $db->prepare($additional_links_query);
    $res->execute();
    
    // Here, we're going to replace each ? placeholder with
    // a corresponding ref_link_id from $ref_links_arr.
    while ($ref_link_id = array_shift($ref_links_arr)) {
        // "i" is for "integer", so if your id field is
        // string, use "s"
        $res->bind_param("i", $ref_links_id);
    }
    
    while ($info = $res->fetch()){
        $li_text = ($info['_ad_text'] == NULL)? '' : ' - '.$info['_ad_text'];
        $li_target = ($info['_ad_url_target'] == NULL)? '' : ' target="'.$info['_ad_url_target'].'"';
        $li_nofollow = ($info['_ad_nofollow'] == 1)? ' rel="nofollow"' : '';
        $li_cont = '<li><a href="'.$info['_ad_url'].'"'.$li_target.$li_nofollow.'>'.$info['_ad_anchor'].'</a>'.$li_text.'</li>';
    
        print "$li_cont\n";
    }
    

    【讨论】:

      【解决方案3】:

      评论行

      $res->execute();
      

      因为你也在尝试执行和获取..PHP's PDO execute() vs. fetch()?

      【讨论】:

        【解决方案4】:

        您已经在使用准备好的语句,您不妨在注入数据库之前绑定您的数据:

        $additional_links_query = 'SELECT * FROM additional_links WHERE id = :value ORDER BY ID asc';
        $res->bindValue(':value',$amount);
        $res = $db->prepare($additional_links_query);
        $res->execute();
        

        如果您不想立即循环查看结果,可以使用PDO::FETCH_ASSOC。当然,这将返回一个关联数组,您必须在以后对其进行解析。

        $res->fetch(PDO::FETCH_ASSOC);
        print_r($res);
        

        【讨论】:

          猜你喜欢
          • 2013-09-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-08-09
          相关资源
          最近更新 更多