Using Custom Variables with PHP Prepare statement - php

Here I go... I have a search function for users, like this:
if ($_GET['s_country']){
$s_country = htmlentities($_GET['s_country'],ENT_QUOTES,"UTF-8");
$s_country=trim($s_country);
$s_country_row = " and country= ?";
} else {
$s_country="";
$s_country_row = " and (country= ? or not country= '')";
}
$s_city = "";
$s_city_row = " and (city= ? or not city= '')";
if ($_GET['s_city']){
$s_city = strip_tags($_GET['s_city']);
$s_city=trim($s_city);
$s_city_row = " and city= ?";
}
$search = mysqli_prepare($dbconnect, "SELECT id FROM user WHERE gender=? $s_country_row $s_city_row");
mysqli_stmt_bind_param($search, 'iss', $s_gender, $s_country, $s_city);
In the above example I have used my own way to dismiss variables. I need to dismiss/remove variables that are not searched for or have no input.
If "country" is not searched for, it should return all rows with all "country" values.
Is there any better way to do this? (Without prepare statement it is quite easy to customize everything, but I hope security does not mean less flexibility).
Thank you for reading this

$country = isset($_GET['s_country'])? " AND country=\'$_GET['s_country']\'" : '';
$query = " SELECT id FROM user WHERE gender=? $country ";
This is the pseudo idea
here query is forming in such a way that
- if it contains country then : SELECT id FROM user WHERE gender=? and country = 'US';
- if country is not defined then : SELECT id FROM user WHERE gender=?
as no conditions for country in the second query this will throw all country rows with particular gender

Related

Constructing a table from a MySQL database, and then being able to filter the table without reloading the page

I'm working on a website that presents leaderboard data from a MySQL database as a table, that which can be filtered and searched through by the user. I was able to construct the table through PHP calls, such as
php echo $row['ranking'];
Similarly, I was able to create a pagination that limits the MySQL query to 50 rows per page.
What I haven't been able to achieve, is the filtering/searching of the data, as well as a pagination that doesn't require the reloading of the page. I attempted to create filtering through PHP variables
$sql = "SELECT * FROM New_2v2_Data $filters";
but couldn't get it to work outside of just editing the PHP code.
$racevar = '%';
$classvar = '%';
$specvar = '%';
$playervar = '%';
$realmvar = '%';
$factionvar = '%';
$r1 = '0';
$r2 = '1800';
$race ="raceId LIKE '$racevar'";
$class = "classId LIKE '$classvar'";
$spec ="specId LIKE '$specvar'";
$player ="player LIKE '$playervar'";
$realm ="realmName LIKE '$realmvar'";
$faction="factionId LIKE '$factionvar'";
$rating ="rating between $r1 and $r2";
$filters = "WHERE $race AND $class AND $spec AND $player AND $realm AND $faction AND $rating";
$sql = "SELECT * FROM New_2v2_Data $filters";
$rs_result = mysql_query ($sql); //run the query
I've found filtering solutions for individual variables, for example names, but I haven't been able to find anything that takes in multiple variables into account. Even then, the filtering only worked on tables that were static.
I was thinking maybe if a dropdown/checkbox were to change a PHP variable depending on what is chosen, and then reloading the PHP for the table to include the additional "WHERE" statement, filtering could work.
Some advice on how I would go about doing this would be great, thank you.
You can conditionally include the various limits and build the SQL just from those which have something set.
$racevar = 'a'; // A value to show when this would be included
$classvar = '%';
$specvar = '%';
$playervar = '%';
$realmvar = '%';
$factionvar = '%';
$r1 = '0';
$r2 = '1800';
$condition= [];
$bindData = [];
if ( $racevar != '%'){
$condition[] ="raceId LIKE ?";
$bindData[] = $racevar;
}
if ( $classvar != '%'){
$condition[] = "classId LIKE ?";
$bindData[] = $classvar;
}
// Repeat above for all of the conditions
if ( $r1 != 0 or $r2 != 0 ) {
$condition[] = "rating between ? and ?";
$bindData[] = $r1;
$bindData[] = $r2;
}
$sql = "SELECT * FROM New_2v2_Data";
if ( count($condition) > 0 ) {
$sql .= " WHERE ".implode(' and ', $condition);
}
echo $sql;
The idea is to build a list of conditions, only when the values have something which is a limit. This can then be added as a where clause.
You then can have various input fields/select fields which allow the user to select the criteria and call this routine with the selections.
I've updated the answer to use bind variables, so that using prepare will give you more security and then you can either bind the values or (using PDO) execute with the array of bind values.
You need to make the filters selectable or dynamic in a way that you can pass them on to your SQL statement.
Your solution for the dropdown could be one of them indeed. You could even do that with a 'search' input text field. Then you make your WHERE statement:
WHERE (`column1` LIKE '%$search%' OR `column2` LIKE '%$search%' OR `column3` LIKE '%$search%',) LIMIT 0,10

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."'";
}

SELECT MYSQL record containing 2 possible values

I would like to Select rows where a value is being returned. If they have chosen Male or Female in the select box, I would want it to search for that. That part is working fine. However, if they choose Either, I want it to say that MySQL should look if the column contains Male or Female and return any results.
Please note that I do not want to use OR statements inside the query if possible based on how the code is being written out.
I tried the below, but it did not seem to work. The values are coming from a select box in a form which has Either, Male or Female.
if ($postgender == "either")
{
$male = "Male";
$female = "Female";
$postgenderuse = ($male || $female);
}
else {
$postgenderuse = $postgender;
}
$query4 = mysql_query("SELECT * FROM tennis WHERE gender='$postgenderuse' ORDER BY playerid DESC LIMIT 0,20");
start creating the query from statements, also check if the form is sending one of the 3 values (just to make sure)
if ($postgender == "Either")
{
$postgenderuse = " ( `gender`='Male' OR `gender`='Female' ) ";
}
elseif ($postgender == "Male" || $postgender == "Female") {
$postgenderuse = " `gender`='".$postgender."' ";
}
else {
die('Error, no gender selected');
}
$query4 = mysql_query("SELECT * FROM `tennis` WHERE ".$postgenderuse." ORDER BY `playerid` DESC LIMIT 0,20");
Assuming that you're treating gender in binary terms, as consisting of only two options (Male, Female):
$sql = "SELECT * FROM tennis";
if(in_array($postgender, array("Male", "Female"))
{
$sql .= " WHERE gender=".$postgender;
}
$sql .= " ORDER BY playerid DESC LIMIT 0,20)";
$query4 = mysql_query($sql);
if It is either, then change your query to do a wild card search.
SELECT * FROM tennis WHERE gender LIKE '$postgenderuse'
That way, when they choose either, you can set postgenderuse to a % Sign.
Although, it might be a better idea to just use OR in your query, and build your query off of conditions, like:
if($postgender == "Male") {
$condition = "WHERE gender='Male'";
} else if($postgender == "Female") {
$condition = "WHERE gender='Female'";
} else {
$condition = "";
}
$query = "SELECT * FROM tennis " . $condition . " ORDER BY BLAH";
In anycase, either way should work. Being able to construct queries from conditionals is part of the power of php.
~ Dan
The solution you have tried would work if you were using Bitwise instead of String for the field gender.
What I suggest, is to use the SQL IN function.
Something like:
$query = "SELECT * FROM tennis WHERE gender IN ('" + implode("', '", $postGenderArray) + "')";

Categories