I need to set up a SQL query with multiple parameters that are being pulled from the URL. So far I can only get it to work with the there is only one item in the URL.
My default query to pull in all the content
$sql = "SELECT ";
$sql .= "* ";
$sql .= "FROM ";
$sql .= "cms_site_content ";
$sql .= "WHERE ";
$sql .= "1";
I then check if anything was passed through the URL and retrieve it.
if (isset($_GET["d"])) {
$d=$_GET["d"];
Inside the if statement, I break the values passed as "d" into separate items
$newD = explode(',',$d);
$countD = count($newD);
foreach($newD as $discipline) {
if ($countD == 1) {
$sql .= " AND";
$sql .= " discipline='".$discipline."'";
}
My problem is getting the SQL to work if there is more than one discipline value. It should read something like this:
SELECT * FROM cms_site_content WHERE 1 AND discipline="value"
however if there's more than one discipline value, it should read:
SELECT * FROM cms_site_content WHERE 1 AND discipline="value OR discipline="value2" OR discipline="value3"
Is there a more efficient way to write this? I can't figure out how to insert the OR into the foreach statement.
Save all discipline values in an array;
$discipline_arr = array();
foreach($newD as $discipline) {
$discipline_arr[] = $discipline;
// by the way, don't forget to escape for sql injection
// mysql_escape_string is the depracated one, u can use that if u have no
// other choice
}
Then in your sql, add them as discipline in ('value1','value2', 'etc ...') condition (that is for strings, for numeric types it would be like discipline in (1,2,3,4, etc)
$sql = " SELECT * FROM cms_site_content WHERE 1 " .
(empty($discipline_arr) ? "" : "and
discipline in ('". implode("','" , $discipline_arr). "') ") ;
Link to escaping
http://tr1.php.net/manual/en/function.mysql-escape-string.php
Assuming the rest of your query is in tact. Simply store all of your discipline values in an array as follows, then feed the $discipline_string to your $sql query:
$discipline_ary = array('option1', 'option2', 'option3');
$discipline_string = "";
for($i=0; $i < count($discipline_ary); $i++){
$discipline_string .= " discipline = '" . $discipline[$i] . "' ";
if($i+1 == count($discipline_ary)){
break;
}else{
$discipline_string .= " OR "
}
}
Related
I'm trying to build a back end solution to a web page project for a class i'm taking. The class doesn't cover anything about back end coding so I've had to learn everything myself. I want to understand how to utilize prepared statements and joins in the PHP code below. There are three tables in my database, but i only want back the data from one of them and only sometimes need to reference the other two to hone in my search.
The code currently works as expected, but is vulnerable to sql injection. I'm getting three form inputs from the user: a text input ($_POST["spell_name"]), a select element ($_POST["classList"]), and some checkboxes ($_POST["school"]). It still needs to work when the checkbox sends an empty array (none of the checkboxes are checked) and the select element sends the default value "all".
$sql = "SELECT * FROM dnd5_spells WHERE ";
if($_POST["classList"] != "all"){
$sql .= "spell_id= ANY(SELECT spell_id FROM dnd5_class_spells WHERE class_id = ANY(SELECT class_id FROM dnd5_classes WHERE class_name='{$_POST["classList"]}')) AND";
};
$sql .= " spell_name LIKE '%{$_POST["spell_name"]}%'";
if(!empty($_POST["school"])){
$sql .= " AND (";
$spellschools = $_POST["school"];
$valueLength = count($spellschools);
for ($x = 0; $x < $valueLength; $x++) {
if ($x>0) {
$sql.= " OR";
};
$sql .= " spell_type" . " LIKE" . " '%" . $spellschools[$x] . "%'";
};
$sql .= ")";
};
$result = mysqli_query($conn, $sql);
How do i make a prepared statement when i can receive all or none of the possible input values and i don't know what i'm getting ahead of time (in my case sending the form data blank returns the entire table and this is good)? Can i iterate over an array into a prepared statement when the array can either be empty or have multiple values? Should i be concerned about including sections of the sql query when that part of the query isn't needed?
Also, i know my use of ANY could possibly be replaced with a JOIN, but i couldn't wrap my head around it and it's less important to me than figuring out the prepared statement issue.
Here is the solution I found. I needed to use PDO then build my statement as I went with prepared statements in mind, placing ? where I wanted my input data, and at the same time build an array with the corresponding data values. I doubt it's perfect but it works just as well as my initial code and is less susceptible to SQL injection.
$sql = "SELECT * FROM dnd5_spells WHERE ";
$parameters = [];
if($_POST["classList"] != "all"){
$sql .= "spell_id= ANY(SELECT spell_id FROM dnd5_class_spells WHERE class_id = ANY(SELECT class_id FROM dnd5_classes WHERE class_name= ?)) AND";
$parameters[] = $_POST["classList"];
};
$sql .= " spell_name LIKE ?";
$parameters[]= "%" . $_POST["spell_name"] . "%";
if(!empty($_POST["school"])){
$sql .= " AND (";
$spellschools = $_POST["school"];
$valueLength = count($spellschools);
for ($x =0; $x < $valueLength; $x++){
if ($x>0){
$sql.= " OR";
};
$sql.= " spell_type LIKE ?";
$parameters[] ="%" . $spellschools[$x] . "%";
};
$sql .= ")";
};
//bind the peramaters into the prepared statment
$stmt = $conn->prepare($sql);
$stmt->execute($parameters);
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
I'm trying to filter through my database according to filters done by visitors.
$query = "select * from Sheet1 where";
//filter query start
if (!empty($brand)) {
$branddata = implode("','", $brand);
//testing removing query
$query .= " Brand in('$branddata') and";
}
if (!empty($model)) {
$modeldata = implode("','", $model);
//testing removing query
$query .= " Model in('$modeldata') and";
}
/* if(!empty($model) && empty($brand)){
} */
if (!empty($spower) && !empty($epower)) {
$query .= " Power>='$spower' and Power<='$epower' and";
}
if (!empty($sprice) && !empty($eprice)) {
$query .= " Doors>='$sprice' and Doors<='$eprice'";
}
$rs = mysqli_query($conn, $query) or die("Error : " . mysqli_error($conn));
The result I wish to get is a sql query that works and has correct syntax. Such as select * from Sheet1 where Doors>='$sprice' and Doors<='$eprice', if the visitor is filtering by price.
Currently, my code is made so that it simply adds a certain string to the variable. This means that if you don't filter by model, it skips model, because the model variable is empty. The problem comes to if you filter by power, the SQL will become select * from Sheet1 where Power>='$spower' and Power<='$epower' and. Obviously this doesn't work, so I need help in making the code make sure it works for every combination of filters.
Append $query .= " 1 = 1"; at the end. I did some modification in your given code. Have a look.
<?php
$query = "SELECT * FROM `Sheet1` WHERE";
//filter query start
if(!empty($brand)){
$branddata = implode("','",$brand);
$query .= " (Brand in('$branddata')) AND";
}
if(!empty($model)){
$modeldata = implode("','",$model);
$query .= " (Model in('$modeldata')) AND";
}
if(!empty($spower) && !empty($epower)){
$query .= " (Power>='$spower' AND Power<='$epower') AND";
}
if(!empty($sprice) && !empty($eprice)){
$query .= " (Doors>='$sprice' AND Doors<='$eprice') AND"; //Added 'AND'
}
$query .= " 1 = 1"; //Added new line
$rs = mysqli_query($conn,$query) or die("Error : ".mysqli_error($conn));
?>
Add AND on each query appended in if conditions. Then, at last add $query .= " 1 = 1";. Which will save you from extra AND coming at the end. If none of the conditions satisfy, then your query will be SELECT * FROM Sheet1 WHERE 1 = 1. Simple. And, don't forget to differentiate between conditions in query. Differentiate your conditions like how I did by opening and closing brackets.
I would do it this way
$filters=array();
if(!empty($brand)){
$branddata =implode("','",$brand);
//testing removing query
$filters[]= " Brand in('$branddata')";
}
if(!empty($model)){
$modeldata =implode("','",$model);
//testing removing query
$filters[]= " Model in('$modeldata') and";
}
if(!empty($spower) && !empty($epower)){
$filters[]= " Power>='$spower' and Power<='$epower' and";
}
if(!empty($sprice) && !empty($eprice)){
$filters[]= " Doors>='$sprice' and Doors<='$eprice'";
}
$query = "select * from Sheet1 where";
foreach ($filters as $filter) {
$query.=' AND '.$filter;
}
$rs = mysqli_query($conn,$query) or die("Error : ".mysqli_error($conn));
There's something with my query, but I cannot manage to find what.
$keys = array_keys($fields);
$values = array_values($fields);
$sql = "UPDATE " .$table. " SET " .implode("`, `", $keys) ."='".implode("', '", $values) . "' WHERE id={$id}";
And it shows as : UPDATE users SET name, password'Rick is vets', 'sdfg' WHERE id=5
But it has to show as : UPDATE users SET name = 'Rick is vets', password='sdfg' WHERE id=5
Try looping through the $fields array to create an update string like this:
$update_string='';
foreach ($fields as $key=>$value)
{
$update_string .= $key."='$value', ";
}
Then remove the last comma character from the string using rtrim() function:
$update_string = rtrim($update_string, ", ");
Then your query becomes:
$sql = "UPDATE " .$table. " SET " .$update_string. " WHERE id={$id}";
This is just to illustrate the concept since your code might still be
open to SQL injection attacks, in which case you should use prepared
statement.
$setString='';
foreach($fields as $k=>$v){
$setString .=$k." = '".$v."', ";
}
$setString=rtrim($setString,', ');
include $setString in query
Hi I'm using PHP to try and retrieve data from a database while looping through an array inside the in statement like this.
$sql2 = "SELECT * FROM pixacour_pixacourt.UserCaseMessages WHERE FavorIDs IN (" ;
$count = 0;
foreach($followingArray as $value)
{
if($count==count($followingArray)-1)
{
$sql2 .= "LIKE";
$sql2 .= "%'".$value."'%";
}
else
{
$sql2 .= "LIKE";
$sql2 .= "%'".$value."'%,";
}
++$count;
}
$sql2 .= ")";
I get this error, that says
"trying to get property of non object"
I can't figure out what is going on any suggestions would be much appreciated thank you for your time.
You should not be using LIKE in an IN clause but you do need to comma delimit elements. No need to keep track of the count, either. foreach will cease when the array has been traversed and you can trim off the trailing comma.
$sql2 = "SELECT * FROM pixacour_pixacourt.UserCaseMessages WHERE FavorIDs IN (" ;
foreach($followingArray as $value)
{
$sql2 .= "'".$value."', ";
}
$sql2 = rtrim($sql2,',');
$sql2 .= ");";
If this fails, like Gordon says, echo $sql2 and the syntax error will probably be clear.
If you do indeed need to use LIKE and wildcard matching, you could append multiple OR clauses, one for each $value.
$sql2 = "SELECT * FROM pixacour_pixacourt.UserCaseMessages WHERE " ;
$whereClause = "";
foreach($followingArray as $value)
{
$whereClause .= " OR FavorIDs LIKE '%".$value."%' ";
}
$whereClause = ltrim($whereClause, " OR");
$sql2 .= $whereClause . ";";
UPDATE 1/9/15
I realized there's a bug in this code in that when $followingArray is empty, we'd receive a MySQL syntax error because the query ends with "WHERE". Here's a new version which resolves that bug:
$sql2 = "SELECT * FROM pixacour_pixacourt.UserCaseMessages" ;
if(count($followingArray) >= 1) {
$sql2 .= " WHERE";
}
$whereClause = "";
foreach($followingArray as $value)
{
$whereClause .= " OR FavorIDs LIKE '%".$value."%' ";
}
$whereClause = ltrim($whereClause, " OR");
$sql2 .= $whereClause . ";";
I have 4 filters for a catalog (name , id, date, price). Those are inputs from the user to see specific data from the database. Those 4 filters are going to produce 4^2 (16) sql_queries on php , because some of the filters may be null. Is there a better way to make queries less ?
example:
if(isset($_POST['filters']))
{
$date = $_POST['date'];
$timi = $_POST['timi'];
$employee = $_POST['dropdown_users'];
$proion =$_POST['dropdown_proionta'];
$query = ("SELECT * FROM id_of_orders WHERE username='$employee' AND price = '$timi' AND time = '$date' AND proion='$proion'");
$result=mysql_query($query);
while($row= mysql_fetch_array($result))
{
echo $row['id_order'] . " " . $row['time'] . '<br>';
}
}
I think you are looking for something like this:
$query = "SELECT * FROM id_of_orders WHERE 1=1";
if(!empty($employee))
$query .= " AND username='$employee'";
if(!empty($timi))
$query .= " AND price='$timi'";
if(!empty($date))
$query .= " AND time='$date'";
if(!empty($proion))
$query .= " AND proion='$proion'";
This way no query conditions are added for empty filters, while entered filters will be used as conditions for the results.