I am trying to expand the functionality of a dictionary I am building by showing definitions for some of the terms (if a definition exists).
I take the data from the two tables as follows:
$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");
After that, in the while loop, I first get the theme name (from another table), then add the query results to an array:
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
);
After that, I try to check if the LEFT JOIN has actually returned any results from the definitions table, and if yes, add those to the array as well - but this is where I fail...
// 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']);
}
I've tried all ways I could find to first check if the variables have been defined, and then push them to the $results array. Nothing works.
I don't seem to be able to successfully find out of english_definition and/or bulgarian_definition are set. When I run the query itself in PhpMyAdmin, it works just fine.
The only "solution" I can think of is to scrap the idea of having a separate table for the definitions and just expand the main table, but that's not a great approach I know. Any insight as to what I am doing wrong will be greatly appreciated. Thanks!
EDIT: I've changed the way elements are added to the array:
// 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'];
}
And this now does the trick. When I dump the $results array outside of the while loop, both definitions have been added.
However, I now get a large number of Warning: Illegal string offset 'theme' in... and 'english' and 'bulgarian' - this happens below, when I run the $results array in a foreach loop to start printing them:
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']);
}
No idea yet why this happens, will keep looking.
SECOND EDIT: Decided to put the two definitions directly inside the $results array as follows:
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
This now works just fine. When I dump the array, if no definition exists, I have 'english_definition' => null and if a definition exists, it's there. So far so good.
The new problem is that I can no longer group the results by theme - the theme of the last result found is shown. Which is a different problem altogether. What really irks me is that before I added the definitions, everything worked just fine. You can the working website here.
PROBLEM SOLVED!
- Decided against pushing values to the array (as shown above).
Got rid of the extra query within the
whileloop 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");
And the while loop is:
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
The website link from above will now load the upgraded search functionality, where definitions will be shown (if they exist). One example word for anyone curious is "worm".
As it turns out, sometimes all it takes to fix a problem is to show it to people and then start thinking about it, as sometimes the solution is right in front of you. Thanks to all who participated!
print_r($results)to see thearray_push()worked, but just added them as new array elements, instead of added them to the$result[]that you created in the loop.print_r($results)butarray_pushdoesn't add the new elements - because bothenglish_definitionandbulgarian_definitionare NULL, I suppose. Neither does$results[] = $row['english_definition'].