Reputation: 41
I have a page where you can filter users by their profile information.
I had 4 different filters that were "City", "Age Above", "Age Below", and "Gender".
I made it work this way, putting every possible combination as an if statement so that all the filters could work separately or in any combination:
if (isset($ageabove)
&& empty($agebelow)
&& empty($gender)
&& empty($city)
)
{
$sql = mysqli_query($con, "select * from Users1
WHERE age >= 1
");
}
This worked, but it was a lot of combinations and I did fear that this may be an inefficient way to do it.
Now I decided that I need to add 1 more filter, making it a total of 5 filters. This would increase the amount 'if' statements exponentially and I am wondering if there is a better way to accomplish this?
If I haven't been clear enough, please let me know.
Any help much appreciated!
Upvotes: 0
Views: 604
Reputation: 4944
To make your filters more dynamic, register them in the database, like that:
You can create a model_filters
table (in mysql for example):
drop table if exists model_filters;
create table model_filters (
id int not null auto_increment primary key,
name varchar(80) not null,
model varchar(80) not null,
condition varchar(40) not null,
created datetime,
modified datetime,
active boolean not null default 1,
index model_filters (name)
);
So, create some filters, for specific model:
INSERT INTO model_filters VALUES
('Age Above' , 'user' ,'age <= %filter'),
('Age Below' , 'user' ,'age >= %filter'),
('City' , 'user' ,'city ="%filter"'),
('Gender' , 'user' ,'gender = "%filter"');
Then, get the filters based in your model:
SELECT id, name FROM model_filters WHERE model = 'user' AND active = 1
Iterate this values and generate a filters <select>
:
<select name="filters" id="filters">
<option value="1">Age Above</option>
<option value="2">Age Below</option>
<option value="3">City</option>
<option value="4">Gender</option>
</select>
<input type="text" name="value" id="value">
And, you get this information, search for selected filter, and then execute your query
<?php
// I'm using PDO
$statment = $pdo->prepare("SELECT * FROM model_filters WHERE id = :id");
$statment->bindValue(':id', $_POST['filters']);
$status = $statment->execute();
$result = null;
if ($status == true) {
$result = $statment->fetchAll(PDO::FETCH_ASSOC);
}
if ($result == null) {
// ERROR!
}
Now, organize the values
/*
$result['condition'] is equal (for example): "age <= %filter"
After replace is = "age <= :filter"
Obs.: replace for whatever you want, for example: ":filtername, :value, :whatever"
*/
$condition = str_replace('%filter', ':filter', $result['condition']);
$statment = $pdo->prepare("SELECT * FROM Users1 WHERE $condition");
$statment->bindValue(':filter', $_POST['value']);
$status = $statment->execute();
$result = null;
if ($status == true) {
$result = $statment->fetchAll(PDO::FETCH_ASSOC);
}
Get $result
, sent for your view, and iterate the filtered users.
Done!
Upvotes: 0
Reputation: 32242
Don't store age
in a database. Unless the user specifically goes in and edits it they will be whatever age they signed up as forever. Store their birthdate and calculate age on the fly with:
SELECT DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(dob, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(dob, '00-%m-%d')) AS age
I prefer to do this for dynamic conditions in SQL queries:
$query = 'SELECT * FROM table';
$conditions = array();
$parameters = array();
if( isset($_GET['cond1']) ) {
$parameters[] = $_GET['cond1'];
$conditions = 'column1 = ?';
}
if( isset($_GET['cond2']) ) {
$parameters[] = $_GET['cond2'];
$conditions = 'column2 = ?';
}
// etcetera...
if( ! empty(conditions) ) {
$query .= ' WHERE ' . implode(' AND ', $conditions);
$sth = $db->prepare($query);
$rs = $sth->(execute($parameters));
} else {
$sth = $db->prepare($query);
$rs = $sth->(execute());
}
if( ! $rs ) { /* error message */ }
// yadda yadda yadda
Which will build you a query like:
SELECT * FROM TABLE WHERE column1 = ? AND column2 = ? AND ... columnN = ?
as well as placing all of your arguments into the array in the proper order.
I might be a little squiffy on the parameterization for MySQLi, though. I'm a PDO guy.
Upvotes: 1
Reputation: 4742
$query = "SELECT stuff FROM table WHERE foo=1 ";
if ($filter1) {
$query .= "AND filter1 = $val";
}
if ($filter2) {
$query .= "AND filter2 = $val";
}
// run query
Would something like that work? (if (isset($filter1) && !empty($filter1))
..)
Upvotes: 1