I have two tables 'favorite' and 'image':
- 'favorite' - contains columns:
- username (varchar) unique identifier for user
- viewkey (varchar) unique identifier for image
- action (tinyint) 1 = image was favorited
- created (datetime) time user favorited image
- 'image' - contains columns:
- username (varchar) unique identifier for user that uploaded image
- viewkey (varchar) unique identifier for image uploaded
- title (text) title of image
- tags (text) csv formatted tags describing image
- filename (text) path to image file on server
- uploaded (datetime) time user uploaded
I want to output an array with all images favorited by the currently logged in user so they can view a favorited album.
I am doing so using a custom database class with query building functions adapted from CodexWorld. I am new to joining tables but I wrote the function getJoin() to build an INNER JOIN query between the two tables which produced the following MySQL query:
SELECT image.*
FROM image
INNER JOIN favorite ON image.viewkey=favorite.viewkey
WHERE favorite.username = 'Caddy7676'
GROUP BY image.title, image.tags, image.filename, image.uploaded, image.modified, image.username, image.viewkey
The kicker is when I run this query in phpMyAdmin, 4 correct rows of images are returned but within my php program, only 1 correct row is returned. No others. It also produces an array where all the columns are strings. What am I doing wrong?
- function getJoin() - builds and executes query returning an array
class DB {
private $hostname = DB_HOST;
private $username = DB_USER;
private $password = DB_PASS;
private $dbname = DB_NAME;
public function __construct() {
if (!isset($this->db)) {
// Connect to database
$conn = new mysqli($this->hostname, $this->username, $this->password, $this->dbname);
if ($conn->connect_error) {
die ("Failed to connect with MySQL: " . $conn->connect_error);
} else {
$this->db = $conn;
}
}
}
public function getJoin($table1, $table2, $conditions = array()) {
if (array_key_exists("select", $conditions)) {
$sql = " SELECT ";
$i = 0;
foreach ($conditions['select'] as $tbl => $value) {
$pre = ($i > 0)?' , ':'';
$sql .= $pre . $tbl . "." . $value;
$i++;
}
$sql .= ' FROM ' . $table1;
}
if (array_key_exists("inner_join", $conditions)) {
$sql .= " INNER JOIN " . $table2 . " ON " . $table1 . "." . $conditions['inner_join'] . "=" . $table2 . "." . $conditions['inner_join'];
}
if (array_key_exists("where", $conditions)) {
$sql .= ' WHERE ';
$i = 0;
foreach($conditions['where'] as $key => $value) {
$pre = ($i > 0)?" AND ":'';
$sql .= $pre.$table2 . "." . $key ." = " . "'$value'" ;
$i++;
}
}
if (array_key_exists("group_by", $conditions)) {
$sql .= ' GROUP BY ';
$i = 0;
foreach($conditions['group_by'] as $key => $value) {
$pre = ($i > 0)?", ":'';
$sql .= $pre . $table1 . "." . $key;
$i++;
}
}
if (array_key_exists("order_by", $conditions)) {
$sql .= ' ORDER BY ' . $conditions['order_by'] . ' DESC ';
}
$result = $this->db->query($sql);
if (array_key_exists("return_type", $conditions) && $conditions['return_type'] != 'all') {
switch ($conditions['return_type']) {
case 'count':
$data = $result->num_rows;
break;
case 'single':
$data = $result->fetch_assoc();
break;
default:
$data = '';
}
} else {
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
$data[] = $row;
}
}
}
echo $sql;
return !empty($data)?$data:false;
}
- view_favorites.php passes all parameters to getJoin() and fleshes out the query
$viewFavoritesDB = new DB();
$images = array ();
// Get all favorited images based on logged in username and favorite action
$conditions['select'] = array (
'image' => '*'
);
$conditions['inner_join'] = 'viewkey';
$conditions['where'] = array (
'username' => $_SESSION['username'],
);
$conditions['group_by'] = array (
'title' => '',
'tags' => '',
'filename' => '',
'uploaded' => '',
'modified' => '',
'username' => '',
'viewkey' => '',
);
$images = $viewFavoritesDB->getJoin('image', 'favorite', $conditions);
- var_dump($images)
array (size=8)
'id' => string '53' (length=2)
'title' => string 'Green Triangle' (length=14)
'tags' => string 'green,triangle,2-d' (length=18)
'filename' => string '33238_1648833408.png' (length=20)
'uploaded' => string '2022-04-01 13:16:21.790642' (length=26)
'modified' => string '2022-04-07 01:25:11.000000' (length=26)
'username' => string 'AgBRAT' (length=6)
'viewkey' => string '62473379c82ec' (length=13)