I’m working on a small online system to sort my books, but stumbled upon a problem now I’ve been trying for hours to solve without any luck.
In my database I have a table titles with the book information (title_id, title, author…) and a second table title_relations with the fields title_relation_id, title_id, to_title_id and titlerelation.
When I call upon the information of a book there is a field related titles which is supposed to list all prequels, sequels and spin-offs.
The database looks like this:
titles
title_id 1 title Lord of the Rings: The Fellowship of the Ring ... title_id 2 title Lord of the Rings: The Two Towers ... title_id 3 title Lord of the Rings: The Return of the King ...
title_relations
title_relation_id 1 title_id 1 to_title_id 2 titlerelation prequel title_relation_id 1 title_id 1 to_title_id 3 titlerelation prequel
Now I’m calling up the information for The Fellowship of the Ring and want to be shown links to The Two Towers and The Return of the King. How do I go about getting that information there?
I got it working for one title relation, but for more than that I’d need a
foreach($title_relations as $row) {
}
where it saves the information from title_relations into variables ($to_title_id_1, $titlerelation_1, $to_title_id_2, $titlerelation_2, …), an array or something else like that.
Nothing I tried worked, so any help offered would be highly appreciated.
I’m using PDO to get the database information.
Old code (not working):
try {
$dbh = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
$dbh->exec("SET CHARACTER SET utf8");
if($page == 'title'){
#titles zuordnen
$titles = $dbh->prepare("SELECT * FROM titles WHERE title_id = $id");
$titles->execute();
while($row = $titles->fetch(PDO::FETCH_OBJ)) {
$title = $row->title;
/* deleted the other infos */
}
#title_relations zuordnen
$title_relations = $dbh->prepare("SELECT * FROM title_relations WHERE title_id = $id");
$title_relations->execute();
while($row = $title_relations->fetch(PDO::FETCH_OBJ)) {
$to_title = $row->to_title_id;
$relation_type = $row->titlerelation;
}
#to_title Seriennamen zuordnen
$series_name = $dbh->prepare("SELECT * FROM titles WHERE title_id = $to_title");
$series_name->execute();
while($row = $series_name->fetch(PDO::FETCH_OBJ)) {
$series = $row->title;
}
}
#Datenbank schließen
$dbh = null; } catch(PDOException $exceptionpdo){
echo 'ERROR: ' . $exceptionpdo->getMessage(); }
Current code (working!):
try {
$dbh = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
$dbh->exec("SET CHARACTER SET utf8");
if($page == 'title'){
// titles zuordnen
// Here I binded the $id in execute, not in prepare
$titles = $dbh->prepare("SELECT title FROM titles WHERE title_id = ?");
$titles->bindParam(1, $id, PDO::PARAM_INT);
$titles->execute();
// Here you are expecting a single row, I guess title_id is a primary key, so you don't needa loop
$row = $titles->fetch(PDO::FETCH_OBJ);
$title = $row->title;
// title_relations zuordnen
$title_relations = $dbh->prepare("SELECT title_relation_id, title_id, to_title_id, titlerelation FROM title_relations WHERE title_id = ?");
$title_relations->bindParam(1, $id, PDO::PARAM_INT);
$title_relations->execute();
$series = array(); // In this array we will store all the related titles
while($row = $title_relations->fetch(PDO::FETCH_OBJ)) {
// zu_title Serieninfo zuordnen
$series_info = $dbh->prepare("SELECT title_id, title FROM titles WHERE title_id = ?");
$series_info->bindParam(1, $row->to_title_id, PDO::PARAM_INT);
$series_info->execute();
while($row = $series_info->fetch(PDO::FETCH_OBJ)) {
$series[] = $row;
}
}
#Datenbank schließen
$dbh = null;
}
} catch(PDOException $exceptionpdo){
echo 'ERROR: ' . $exceptionpdo->getMessage();
}
You shoul supply your query to better understand and adapt this answer to your specific needs.
Without that the simplest example I can think of, basicaly you use just one query with left join to return the title even if it has no relations (good for simple smaller tables). In this example I just print the related titles to STDOUT with an identation.
@update
Based on your code, a working version would be:
@disclaimer, this is based on your code, I am not recomanding to do select in a while loop, I will just use a single query like the version above (or a variation of it).
Your code return just one relation because you query-ed just the last row returned from title_relations. To solve this (
again in the context of your code) I moved the last query in the while of title_relations.To be able to acces all relations I made an
(array)$series, you just store the last row in the(string)$series.