Rewrite query depending on GET parameters - php

I'm working on a search engine on my website. Users can add on criteria which is submitted with a GET in the url.
When users select for example 1 criteria, it looks like this:
localhost/search.php?course=1&price=&name=
They have 3 criteria they can select, so as you see he only selected COURSE.
Now I have to select from the database according to the criteria so my code looks like this:
if ($_GET['price'] > 0 && $_GET['name'])
{
$search_price = $_GET['price'];
$search_name = $_GET['name'];
$result2 = mysql_query("SELECT id, name, price, views, userid, type, anonymous FROM files WHERE course='$course_id' AND price < $search_price AND name LIKE '%$search_name%'");
}
elseif ($_GET['price'] > 0)
{
$search_price = $_GET['price'];
$result2 = mysql_query("SELECT id, name, price, views, userid, type, anonymous FROM files WHERE course='$course_id' AND price < $search_price");
}
elseif ($_GET['name'])
{
$search_name = $_GET['name'];
$result2 = mysql_query("SELECT id, name, price, views, userid, type, anonymous FROM files WHERE course='$course_id' AND name LIKE '%$search_name%'");
}
else
{
$result2 = mysql_query("SELECT id, name, price, views, userid, type, anonymous FROM files WHERE course='$course_id'");
}
while ($row2 = mysql_fetch_assoc($result2))
{
.....
But this can not be the correct way, because if eventually users can select 10 criteria this is going to be a very long code
How do I fix this?

What I would do is dynamically create the sql query,and then execute it at the end. So something like this
$query_string = "SELECT blahblah, blahblah, blah blah from blahx where 1=1 ";
$where = "";
if(isset($_GET['somecriteria']))
{
$where .= " AND blahblah = $_GET['somecriteia'] ";
}
if(isset($_GET['someOTHERcriteria']))
{
$where .= " AND blahblah=$_GET['someOTHERcritera'] ";
}
mysql_query($query_string . $where);
etc..
Take note this is just to show you how to achieve your objective. This is obviously prone to SQL Injection attacks and you'd have to clean the stuff up.

Use $_post to send larger amounts of information to the php script. When using get you should create the url to include get calls only if they are populated. As such if no price is selected the url should not include "price=". This will cause problems with your receiving script.
Your database script can be done with one call including only the selected criteria.
Myqsl has been depreciated, you need to look into Myqsli or PDO

Related

Making a live search function

I've made a crud function where users register/log in to view their own contact list. The mysql database has tables of details such as name, mobile, email, company, title etc. I want to implement a live search function where the user can type in something such as e.g. first name + title or whatever random combination, and for the live search to be able to match the search field(s).
What is your recommendation in making something that fulfills the above?
Many thanks!
$result = array();
$Query = "SELECT * FROM contact_list WHERE ";
$keyword = preg_split("/[\s,-]+/", $q);
$flag = 0;
while ($flag<count($keyword))
{
if($flag==0)
$Query.=" name LIKE '%".$keyword[$flag]."%' OR title LIKE '%".$keyword[$flag]."%'";
else
$Query.=" OR name LIKE '%".$keyword[$flag]."%' OR title LIKE '%".$keyword[$flag]."%'";
$flag++;
}
$Query .= " ORDER BY `name` ASC";
$exec = $this->db->query($Query);
foreach ($exec->result() as $row)
{
array_push($result,$row);
}
This code i have done in codigniter. you can change it as you needed.. i hope this is you want.

PHP MySQL: Fetching all associated rows from multiple tables using one query?

For a recipe app I've got one table storing general recipe info and an id. I've then got several other tables tables storing associated data like ingredients, instructions, notes and so on. At the moment I'm fetching and connecting all this data using multiple simple SQL statements.
However I now need to put the entire result (everything relating to one recipe, via its "recipe_id") into one single array so that I can manipulate it as one entity.
I first tried array_merge but then got on using JOINs but I'm not certain that they do what I like. Is that the route I need to take of are there other options?
Here is my current code:
$conn = connDB();
// Get basic recipe data
$sql = "SELECT recipe_id, date_created, name, description, author, cooktime, preptime, totaltime, yield, category_id, cuisine_id, image, image_url, url FROM recipes WHERE recipe_id=" . $recipe_id . " LIMIT 1";
$result = $conn->query($sql);
// Check that we get a result - ie a valid recipe_id
if ($result->num_rows > 0) {
$basicrow = $result->fetch_assoc();
// Get ingredients
$sql = "SELECT recipe_id, ingredient_id, ingredient, uom_id, ingredient_quant FROM ingredients WHERE recipe_id=" . $recipe_id . "";
$ingredientresult = $conn->query($sql);
$ingredientrow = $ingredientresult->fetch_assoc();
// Get Units Of Measurements
$sql = "SELECT uom_id, uom_long, uom_short FROM uom";
$uomresult = $conn->query($sql);
if ($uomresult->num_rows > 0) {
$uomArray = array();
while($uomrow = $uomresult->fetch_assoc()) {
$uomArray[$uomrow['uom_id']]["uom_id"] = $uomrow['uom_id'];
$uomArray[$uomrow['uom_id']]["uom_long"] = $uomrow['uom_long'];
$uomArray[$uomrow['uom_id']]["uom_short"] = $uomrow['uom_short'];
}
}
// Get instructions
$sql = "SELECT recipe_id, instruction_id, instruction FROM instructions WHERE recipe_id=" . $recipe_id . "";
$instructionresult = $conn->query($sql);
// Get notes
$sql = "SELECT recipe_id, date_created, note FROM notes WHERE recipe_id=" . $recipe_id . "";
$notesresult = $conn->query($sql);
} else {
echo "No such recipe"; // Not a valid recipe_id
}
$conn->close();
You could create associative arrays keyed off of recipe id, then you could loop through them and combine the information in the form you want. Using joins is the best way to get this data in one array. The only caveat I have with this is how long it takes the queries to run. I have personally used both approaches, it all depends on what I'm trying to do, and how long it takes the page in question to load.

Dynamic sql search in php

Trying to create a dynamic search functionality.
Goal : allowing user to search by email (if not empty), if empty (by last name), if both are not empty, than by both, etc.
I know I can write if statement depicting every scenario and than insert SQL command based on that, question is can this be handled in a more simplified manner. Thanks for your help.
Current function set up does OR across all fields, values are coming from $_POST:
find_transaction($email,$last_name,$first_name, $transaction_id)
{
GLOBAL $connection;
$query = "SELECT * ";
$query .= "FROM transactions WHERE ";
$query .= "email='{$email}' ";
$query .= "OR last_name='{$last_name}' ";
$query .= "OR first_name='{$first_name}' ";
$query .= "OR transaction_id='{$transaction_id}' ";
$query .= "ORDER BY date DESC";
$email = mysqli_query($connection,$query);
confirm_query($email);
return $email;
}
I do this all the time, it's not too much work. Basically build your WHERE statement dynamically based off your POST variables, using a series of if statements.
For example:
$where_statement = "";
// First variable so is simpler check.
if($email != ""){
$where_statement = "WHERE email = '{$email}'";
}
// Remaining variables also check if '$where_statement' has anything in it yet.
if($last_name != ""){
if($where_statement == ""){
$where_statement = "WHERE last_name = '{$last_name}'";
}else{
$where_statement .= " OR last_name = '{$last_name}'";
}
}
// Repeat previous 'last_name' check for each remain variable.
SQL statement would change to:
$query = "SELECT * FROM transactions
$where_statement
ORDER BY date DESC";
Now, the SQL will only contain filters depending on what values are present, so someone puts in just email, it would generate:
$query = "SELECT * FROM transactions
WHERE email = 'smith#email.com'
ORDER BY date DESC";
If they put in just last name, it would generate:
$query = "SELECT * FROM transactions
WHERE last_name = 'Smith'
ORDER BY date DESC";
If they put both, would generate:
$query = "SELECT * FROM transactions
WHERE email = 'email#email.com' OR last_name = 'Smith'
ORDER BY date DESC";
Etc., etc.
You could add as many variables you wish here, and basically if the specific variable is not blank, it will add it to the "$where_statement", and depending on if there is anything in the "$where_statement" yet or not, it will decide to start with = "WHERE ", or append .= " OR" (notice the '.=' and the space before 'OR'.
Better use Data Interactive table : http://datatables.net/
It's useful and no SQL-injection :) Good luck !

How to make query that ignores undefined variables?

How make mysql search defined just by what is written in html form, by user, and if some form box is stayed empty, mysql should ignore it. For example:
$sql = "SELECT * FROM catalog WHERE name= '".$name."' AND publisher = '".$publisher."' ";
mysql_query($sql);
This query will display all rows where name and publisher are together. Now, what if user insert just name, and left publisher box empty. The idea is that php/mysql ignore empty form box, and display every row with inserted name. But it will not do that because $publisher will be undefined, and error emerges. How to tell musql to ignore $publisher? More generally, the question is: how to generate query that make searching defined by certain criteria if they exists, and if they don't how to just ignore it?
You can build up the sql programmatically. I am assuming you have escaped the values properly.
$sql = "SELECT * FROM catalog";
$wheres = array();
if (!empty($name)) {
$wheres[] = " name = '$name'";
}
if (!empty($publisher)) {
$wheres[] = " publisher = '$publisher'";
}
if (count($wheres)) {
$sql .= " WHERE " . implode (' AND ', $wheres);
}
//RUN SQL
Also have a read through this, you are using a deprecated mysql library.
This will allow either the name or the publisher to be NULL.
<?php
$sql = "SELECT * FROM catalog WHERE (name= '".$name."' OR name IS NULL) AND (publisher = '".$publisher."' OR publisher IS NULL)";
mysql_query($sql);
Try like
$my_var = " ";
if($publisher) //if(!empty($publisher))
$my_var = " AND publisher = '".$publisher."' ";
$sql = "SELECT * FROM catalog WHERE name= '".$name."' ".$my_var;
if the publisher is empty then you need to pass the NULL value and PLZ note that it is a bad practise.It will causes many sql injection issues.Try to put validations for the things

How to select all where the condition is null?

I have a php code with a query:
$query = "SELECT * FROM TDdb WHERE status = $status AND occupation =$occupation";
I am sending the values status and occupation with a client application to this php code.
This works when I send both status and occupation. But I want it to return rows if I just send status but not occupation also ( I mean no matter what the occupation is).
does anyone have any suggestions?
I would appreciate any help.
PS: I want to do it without if statement and just but changing the query
Personally I would create a base query and append conditions wherever you have them, like so:
$sql = 'SELECT * FROM TDdb';
$conditions = array();
$args = array();
if ($action) {
$conditions[] = 'status = :status';
$args[':status'] = $status;
}
if ($occupation) {
$conditions[] = 'occupation = :occupation';
$args[':occupation'] = $occupation;
}
if ($conditions) {
$sql .= ' WHERE ' . join(' AND ', $conditions);
}
$stmt = $db->prepare($sql);
$stmt->execute($args);
Looks like you've got a few good options for how to do it in SQL, or how to make the SQL string variable in PHP.
One reason to consider using an 'if' in the PHP code for the database access performance.
When you introduce an 'or' condition like that in SQL, you're not going to get index access. It is much harder for the database to determine what path it should take than for the PHP code because the SQL engine optimizes the query without knowing what the variable will resolve to at execution.
You already know in the PHP which version of the query you really want. This will perform better if you make that choice there.
This will work if you pass an occupation or a NULL value.
SELECT *
FROM TDdb
WHERE status = $status
AND ($occupation IS NULL OR occupation = $occupation)
"SELECT * FROM TDdb WHERE status = '$status' AND (occupation = '$occupation' OR occupation IS NULL)";
Apart from the solution provided by #Tom and #Damien Legros, you may create two query strings one with occupation and one without occupation. Something like:
$query = "SELECT * FROM TDdb WHERE status = $status";
if ($occupation != "") {
/*When you have value for occupation*/
$query .= " AND occupation =$occupation";
}
So in this case, data will be returned if you have only the status field. Secondly, please check if the status and occupation fields in table are varchar then you have to enclose them in single quotes (').
Thanks everyone for help. specially jack.
finally i created my query like this:
$query = 'SELECT * FROM TDdb';
if ($status) {
$query = $query." WHERE status = '".$status."'";
}
if ($occupation) {
$query = $query." AND occupation = '".$occupation."'";
}

Categories