Is there a simpler way for me to code this and perform the same thing without having to have so many queries? Im trying to add pagination (not included in code here) and it work
And My Second thought:
$sql = 'SELECT * FROM _product JOIN _module_type ON module_type = module_id WHERE';
if(!empty($filter) || !empty($status)){
$sql .= ' module_type = :filter '.(!empty($filter) && !empty($status) ? 'AND' : 'OR').' product_status = :status';
$sth = $link->prepare($sql);
$sth->bindValue(':filter', $filter);
$sth->bindValue(':status', $status);
}else{ $sth = $link->prepare($sql); }
$result = $sth->execute();
It needs testing and as truth said you might not need the OR but that is upto exactly how your form and filtering works tbh, but I am gonna leave it at that it should give you pointers to move to the next stage.
Edit again:
Couldn't help myself, here is a third possibility:
$params = array();
$where = array();
if(!empty($filter)){
$params[':filter'] = $filter;
$where[] = 'module_type = :filter';
}
if(!empty($status)){
$params[':status'] = $status;
$where[] = 'product_status = :status';
}
$sql = 'SELECT * FROM _product JOIN _module_type ON module_type = module_id'.(sizeof($where) > 0 ? ' WHERE '.implode(' AND ', $where) : '');
$sth = $link->prepare($sql);
foreach($params as $k=>$v) $sth->bindValue($k, $v);
$result = $sth->execute();
My thought is to iterate the $_POST
array and bind only the variables you need.
You are misunderstanding the use of AND and OR. If only one of the two is selected, you don't need to OR on the second one!
<?php
/**
* @param PDO $pdo Database connection
* @param array $parameters Parameters (status, filter)
*
* @return array The resultset returned from the query
*/
function select_product(\PDO $pdo, array $parameters = array()) {
$query = <<<MySQL
SELECT *
FROM _product
JOIN _module_type
ON module_type = module_id
MySQL;
if (!empty($parameters)) {
$query .= "WHERE ";
$where_clauses = array();
foreach ($parameters as $param => $value) {
$where_clauses[] = "$param = :$param";
}
$where_clauses = implode(" AND ", $where_clauses);
$query .= $where_clauses;
}
$stmt = $pdo->prepare($query);
foreach ($parameters as $param => $value) {
$stmt->bindValue(":$param", $value);
}
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $results;
}
try {
$db = new PDO("mysql:host=localhost;dbname=database_name", "user", "password");
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
select_product($db, $_POST);
}
catch (PDOException $e) {
die("Database problem occurred! " . $e->getMessage());
}
The code will not work for you as is, so don't copy/paste it right away.
This function assumes that the form names match the database names, and will act accordingly. If your column name is module_type
, name the form field which matches it module_type
as well.
The advantages of such code, is that you can add more columns and more filters, and you won't have to change a single line of code :)