LEFT JOIN,在PHP中如果第二个表存在结果,则将其添加到数组中。

5

我正在尝试通过显示某些术语的定义(如果存在定义)来扩展我正在构建的字典的功能。

我按以下方式从两个表中获取数据:

    $query = $db->query("SELECT * FROM ".DICTIONARY_TABLE." " .
            "LEFT JOIN ".DICTIONARY_DEFINITIONS." ON ".DICTIONARY_TABLE.".id = ".DICTIONARY_DEFINITIONS.".term_id ".
            "WHERE ".DICTIONARY_TABLE.".".$source." LIKE '%".$keyword."%' ".
            "AND ".DICTIONARY_TABLE.".theme_id = ".$selected_theme_id." ".
            "ORDER BY ".DICTIONARY_TABLE.".id");

while 循环中,首先我从另一个表格中获取主题名称,然后将查询结果添加到一个数组中:

        while($row = $query->fetch(PDO::FETCH_ASSOC)) {
    // get theme name
    $theme_name = "theme_".$lang;
    $theme_query= $db->query("SELECT theme_id,".$theme_name." FROM ".DICTIONARY_THEMES." WHERE theme_id = ".$theme_id."");
    $theme_row  = $theme_query->fetch(PDO::FETCH_ASSOC);
    $theme      = $theme_row[$theme_name];

    // add all results to an array
    $results[] = array(
        'english'           => $row['english'],
        'bulgarian'         => $row['bulgarian'],
        'english_abbr'      => $row['english_abbr'],
        'bulgarian_abbr'    => $row['bulgarian_abbr'],
        'theme'             => $theme
    );

在此之后,我尝试检查LEFT JOIN是否从定义表中返回了任何结果,如果是,则将其添加到数组中 - 但这就是我失败的地方...

    // check if definition exists for this term
    if(isset($row['bulgarian_definition'])) {
        array_push($results['bulgarian_definition'], $row['bulgarian_definition']);
    }
    if(isset($row['english_definition'])) {
        array_push($results['english_definition'], $row['english_definition']);
    }

我已尝试所有方法来首先检查变量是否已定义,然后将它们推送到$results数组中,但都没有成功。
我似乎无法成功地找出english_definition和/或bulgarian_definition是否设置。当我在PhpMyAdmin中运行查询本身时,它可以正常工作。
我唯一想到的“解决方案”是放弃为定义创建一个单独的表格,而是扩展主表格,但我知道这不是一个好方法。 如果您能提供任何有关我做错了什么的见解,将不胜感激。谢谢!
编辑:我已更改添加元素到数组的方式。
    // check if definition exists for this term
    if(isset($row['bulgarian_definition'])) {
        $results['bulgarian_definition'] = $row['bulgarian_definition'];
    }
    if(isset($row['english_definition'])) {
        $results['english_definition'] = $row['english_definition'];
    }

现在这个代码已经实现了功能。当我在while循环之外输出$results数组时,两个定义都被加入了。

然而,当我在下面使用foreach循环遍历$results数组并开始打印它们时,出现了大量的Warning: Illegal string offset 'theme' in...以及'english'和'bulgarian'。

    foreach($results as $result) {

    if($theme != $result['theme']) {
        $theme = $result['theme'];
        $search_results .= "<h3>" . $result['theme'] . "</h3>";
    }

    if($source == "english") {
        foreach ($keywords as $keyword) {
            $result['english'] = preg_replace("|($keyword)|Ui", "<span style=\"color:#780223\">" . $keyword . "</span>", $result['english']);
        }

我还不知道为什么会发生这种情况,会继续查找。
第二次编辑:决定将两个定义直接放在$results数组中,如下所示:
    while($row = $query->fetch(PDO::FETCH_ASSOC)) {
    // get theme name
    $theme_name = "theme_".$lang;
    $theme_query= $db->query("SELECT theme_id,".$theme_name." FROM ".DICTIONARY_THEMES." WHERE theme_id = ".$theme_id."");
    $theme_row  = $theme_query->fetch(PDO::FETCH_ASSOC);
    $theme      = $theme_row[$theme_name];

    // add all results to an array
    $results[] = array(
        'english'           => $row['english'],
        'bulgarian'         => $row['bulgarian'],
        'english_abbr'      => $row['english_abbr'],
        'bulgarian_abbr'    => $row['bulgarian_abbr'],
        'theme'             => $theme,
        'bulgarian_definition'  => $row['bulgarian_definition'],
        'english_definition'    => $row['english_definition']
    );  
}// end while

现在这个功能已经完美运行。当我输出数组时,如果没有定义,我会得到'english_definition' => null,如果有定义,则会显示出来。目前为止一切顺利。

新的问题是,我不能再按主题分组结果 - 只显示找到的最后一个结果的主题。这是一个完全不同的问题。真正让我恼火的是,在添加定义之前,一切都很好。您可以在这里查看工作网站。

问题已解决!

  1. Decided against pushing values to the array (as shown above).
  2. Got rid of the extra query within the while loop that gets the theme's name, moving it instead to the query that performs the search. Thus the query itself is:

                    $query = $db->query("SELECT * FROM ".DICTIONARY_TABLE." " .
            "JOIN ".DICTIONARY_THEMES." ON ".DICTIONARY_TABLE.".theme_id = ".DICTIONARY_THEMES.".theme_id ".
            "LEFT JOIN ".DICTIONARY_DEFINITIONS." ON ".DICTIONARY_TABLE.".id = ".DICTIONARY_DEFINITIONS.".term_id ".
            "WHERE ".DICTIONARY_TABLE.".".$source." LIKE '%".$keyword."%' ".
            "ORDER BY ".DICTIONARY_TABLE.".theme_id, ".DICTIONARY_TABLE.".id");
    

while循环是:

    while($row = $query->fetch(PDO::FETCH_ASSOC)) {

    $theme_name = "theme_".$lang;

    // add all results to an array
    $results[] = array(
        'english'           => $row['english'],
        'bulgarian'         => $row['bulgarian'],
        'english_abbr'      => $row['english_abbr'],
        'bulgarian_abbr'    => $row['bulgarian_abbr'],
        'theme'             => $row[$theme_name],
        'bulgarian_definition'  => $row['bulgarian_definition'],
        'english_definition'    => $row['english_definition']
    );  
}// end while

以上的网站链接现在将加载升级后的搜索功能,如果存在定义,则会显示。任何好奇的人都可以看一个例子单词"worm"。

事实证明,有时解决问题所需的只是向人们展示它,然后开始思考,因为有时解决方案就在你面前。感谢所有参与者!


请展示您填充 $row 数组的代码。 - Webeng
你是否执行过 print_r($results) 来查看 array_push() 是否起作用,但是它只是将它们作为新的数组元素添加,而不是添加到你在循环中创建的 $result[] 中。 - Sean
是的,我执行了 print_r($results) 但是 array_push 没有添加新元素 - 我猜是因为 english_definitionbulgarian_definition 都是 NULL。 $results[] = $row['english_definition'] 也没有添加。 - cheeseus
1个回答

0

编辑:由于之前的回答不正确,已经删除。一旦我有解决问题的方法,我会更新这个回答。由于我还没有找到删除选项,所以没有删除这个回答。虽然有时候佔用空间和感觉重要很有趣 : ),但请不要恨玩家,而是讨厌游戏。



看一下 $theme_query 的查询语句,它是 SELECT theme_id,".$theme_name." FROM ...。因此这些列不在 $theme_row 中,而是在外部循环变量 $row 中。 - Sean
@Sean 你说得对。我在他的问题下评论了,要求展示填充 $row 数组的代码,现在考虑到新信息,我会编辑我的回答。 - Webeng
在你的第二部分中,如果你想在每次循环while($row = $query->fetch(PDO::FETCH_ASSOC)) {时添加数组,那么$results[] = array(是正确的。如果返回的行数超过1行,则需要使用$result[],因为只有使用$result时,在每次循环迭代时它才会覆盖先前的值,并且只有最后一次循环的值(们)会被保存。 - Sean
@Sean,如果我有一个名为$result的数组,其中已经有了信息,并且我想要向它添加行,那么我可以使用$result[] = array(...),这会给我与array_push($result, array(...))相同的结果吗? - Webeng
是的。我更喜欢使用$result[]而不是array_push(),但它们基本上做的是相同的事情 - https://dev59.com/PXRB5IYBdhLWcg3wpotm - Sean
@Sean,我的回答全没了。事实上,我从Cheeseus的问题中学到的比他多。也许这不公平,但谁说世界就是公平的呢? - Webeng

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接