Im creating detailed product search.I verified that ,my variables are posted correctly, but the query don't finding anything. My question is:
What could be wrong in this query and what could be the best solution for detailed search in SQL?
<?php
if (
isset($_POST["productName"]) || isset($_POST["searchCategory"]) ||
isset($_POST["searchManufacturer"]) || isset($_POST["costFrom"]) ||
isset($_POST["costTo"])
){
$stmt=$user_home->runQuery("SELECT* FROM Products
WHERE (productTitle='$_POST[productName]' OR '$_POST[productName]' IS NULL)
AND (category='$_POST[searchCategory]' OR '$_POST[searchCategory]' IS NULL)
AND (manufacturer='$_POST[searchManufacturer]' OR '$_POST[searchManufacturer]' IS NULL)
");
echo $stmt->rowCount();
}
Try to proper forming WHERE statement. You should add conditions for productTitle, category, manufacturer fields only then isset proper POST fields.
Try this code:
<?php
if (
isset($_POST["productName"]) || isset($_POST["searchCategory"]) ||
isset($_POST["searchManufacturer"]) || isset($_POST["costFrom"]) ||
isset($_POST["costTo"])
){
$conditions = array();
if (isset($_POST['productName'])) {
$conditions[] = "(productTitle='".$_POST['productName']."')";
}
if (isset($_POST['category'])) {
$conditions[] = "(category='".$_POST['searchCategory']."')";
}
if (isset($_POST['searchManufacturer'])) {
$conditions[] = "(manufacturer='".$_POST['searchManufacturer']."')";
}
$where = implode(' AND ', $conditions);
if ($where) {
$where = 'WHERE '.$where;
} else {
$where = "";
}
$stmt=$user_home->runQuery("SELECT * FROM Products ". $where);
echo $stmt->rowCount();
}
Related
I have a problem code beneath this line does not work! How can I let this work? where ... orWhere orWhere does filter but cumulates the queries. where ... where does not provide any result. Can someone help me?
$artworks = Artwork::where('category_id', $category)
->where('style_id', $style)
->where('technic_id', $technic)
->where('orientation', $orientation)
->get();
Here is the full code:
if (request()->category_id) {
$category = request()->category_id;
} else {
$category = 0;
}
if (request()->style_id) {
$style = request()->style_id;
} else {
$style = 0;
}
if (request()->technic_id) {
$technic = request()->technic_id;
} else {
$technic = 0;
}
if (request()->orientation_id == 'vertical') {
$orientation = 'vertical';
} else if (request()->orientation_id == 'horizontal') {
$orientation = 'horizontal';
} else {
$orientation = 0;
}
$artists = Artist::get();
$artworks = Artwork::where('category_id', $category)
->where('style_id', $style)
->where('technic_id', $technic)
->where('orientation', $orientation)
->get();
return view('frontend.index', compact('artworks', 'artists'));
I think you want to use OR Condition and you are mistaking it with double where. Please look below to understand properly
If you want AND condition in your query then the double where are used but if you want OR condition then you have to use orWhere
Examples:
AND condition
Query::where(condition)->where(condition)->get();
OR Conditon
Query::where(condition)->orWhere(condition)->get();
If you expect all of your variables to be set
Your query variables category_id, style_id, orientation_id & technic_id are being defaulted to 0 if they are not true.
Your query is fine, but you may not have the data you think you do.
Run the following at the top of this function:
print_r($request->all());
exit;
If all of your variables are optional
very procedural, basic way to achieve this:
$artists = Artist::get();
$artworks = Artwork::where('id', '>', 0);
$category_id = request()->input('category_id');
if ($category_id != '') {
$artworks->where('category_id', request()->category_id);
}
$style_id = request()->input('style_id');
if ($style_id != '') {
$artworks->where('style_id', request()->style_id);
}
$technic_id = request()->input('technic_id');
if ($technic_id != '') {
$artworks->where('technic_id', request()->technic_id);
}
$orientation_id = request()->input('orientation_id');
if ($orientation_id != '') {
$artworks->where('orientation_id', request()->orientation_id);
}
$artworks->get();
return view('frontend.index', compact('artworks', 'artists'));
I am currently trying to write complex MySQL WHERE clauses that are generated from $_GET variables (which themselves come from select dropdowns). First, a bit of code so you know what I am talking about:
if(!isset($_GET['order'])){
$order= 'start asc';
} elseif ($_GET['order'] == "dateasc") {
$order= 'start asc';
} elseif ($_GET['order'] == "titleasc") {
$order= 'title asc';
} elseif ($_GET['order'] == "titledesc") {
$order= 'title desc';
};
if(!isset($_GET['cat'])){
$cat= '0';
} else {
$cat = $_GET['cat'];
};
if(!isset($_GET['loc'])){
$loc= '0';
} else {
$loc = $_GET['loc'];
};
if (isset($_GET['sd']) || isset($_GET['ed']) || isset($_GET['cat']) || isset($_GET['loc']) || isset($_GET['order']) ) {
$where = 'WHERE ';
if (isset($_GET['sd'])) {
$where .= "start = " . $_GET['sd'];
};
if (isset($_GET['ed'])) {
$where .= "AND end = " . $_GET['ed'];
};
if (isset($_GET['cat'])) {
$where .= "AND category = " . $_GET['cat'];
};
if (isset($_GET['loc'])) {
$where .= "AND location = " . $_GET['loc'];
};
};
$result = mysql_query("SELECT * FROM " . TABLE . $where . " ORDER BY " . $order);
Obviously this isn't working, otherwise I wouldn't be here. :) Basically, I have 4 variables that I want to conditionally use for sorting in my query: start date, and end date, a category, and a location. My problem is that all 4 of these may not always be used.. so given the above example, there might be a case where someone selects a category ($cat) but NOT a start date ($sd)... which means my WHERE clause would start off with 'AND', which is obviously invalid. So how do I build a query based off variables that may or may not be used?
I really feel like I am overthinking this, and I am afraid of writing 9000 lines of isset tests to account for every combination of $_GET variable usage. Surely there a simple way to build a WHERE clause from multiple $_GETs that may or may not be used every time..? I've tried Googling but can only find solutions that suggest using a framework for building complex queries and that just seems overly... clunky... for such a simple problem.
If you're just worried about having a where clause that starts with AND you can add 1=1 to account for no filters.
WHERE 1=1
Then, if you have any filters, it will look like this:
WHERE 1=1 AND col1=? AND col2=?
This may not be the cleanest solution, but it should be fairly simple to understand and implement.
if (isset($_GET['sd']) || isset($_GET['ed']) || isset($_GET['cat']) || isset($_GET['loc']) || isset($_GET['order']) ) {
$where = 'WHERE ';
if (isset($_GET['sd'])) {
if(strlen($where) > 6) {
$where .= " AND ";
}
$where .= "start = " . $_GET['sd'];
}
if (isset($_GET['ed'])) {
if(strlen($where) > 6) {
$where .= " AND ";
}
$where .= "end = " . $_GET['ed'];
}
if (isset($_GET['cat'])) {
if(strlen($where) > 6) {
$where .= " AND ";
}
$where .= "category = " . $_GET['cat'];
}
if (isset($_GET['loc'])) {
if(strlen($where) > 6) {
$where .= " AND ";
}
$where .= "location = " . $_GET['loc'];
}
}
I have a form that requires the user to only fill out at least 1 (out of four) fields. They can then submit and get a search result based off of their input.
The problem is, I can't get a character to set my variables to that will match any database value. Here is my code for some context;
if (isset($_POST['buildname']) ||
isset($_POST['weapon']) ||
isset($_POST['category']) ||
isset($_POST['id']))
{
if ($_POST['buildname'] == "")
{
$buildname = ".*";
}
if ($_POST['weapon'] == "")
{
$weapon = ".*";
}
if ($_POST['category'] == "")
{
$category = ".*";
}
if ($_POST['id'] == "")
{
$id = ".*";
}
$buildname = sanitizeString($_POST['buildname']);
$weapon = ($_POST['weapon']);
$category = ($_POST['category']);
$id = ($_POST['id']);
$searchstring = "SELECT buildname,weapon,category,id,author FROM weapons " .
"WHERE buildname='$buildname' AND weapon='$weapon' AND category='$category' AND id='$id'";
As you can see, the code looks at if one of the variables is set, then submits a form. If a variable isn't set, it assigns a character of ".*" (which I thought would match anything). It then queries the database to match any rows. I get no results unless I enter EVERY field with a correct entry.
Any ideas?
Thanks!
I would not use %, instead do something like this
if (isset($_POST['buildname']) || isset($_POST['weapon']) || isset($_POST['category']) || isset($_POST['id'])){
$sqlArray = array();
if(isset($_POST['buildname'])){
$sqlArray[] = "buildname='" . mysqli_real_escape_string($connection,$_POST['buildname']) . "'";
}
if(isset($_POST['weapon'])){
$sqlArray[] = "weapon='" . mysqli_real_escape_string($connection,$_POST['weapon']) . "'";
}
if(isset($_POST['category'])){
$sqlArray[] = "category='" . mysqli_real_escape_string($connection,$_POST['category']) . "'";
}
if(isset($_POST['id'])){
$sqlArray[] = "id='" . mysqli_real_escape_string($connection,$_POST['id']) . "'";
}
$searchstring = "SELECT buildname,weapon,category,id,author FROM weapons " .
"WHERE " . implode(' AND ', $sqlArray);
}
The wildcard character for MySQL is: %
The query you are executing, you "thought would match anything" wont. The statement uses no regular expressions.
WHERE buildname='$buildname' AND weapon='$weapon'
Which is essentially saying you need to have the following fields equal their string value of:
WHERE buildname='.*' AND weapon='.*'
I doubt you have any building with a name of .*.
It would be better to not filter on that field. basically remove the WHERE cause criteria if the variable is not defined.
You can do this dynamically, buliding the SQL statement only when you need to filter by that field.
if (isset($_POST['somevalue']) && ! empty($_POST['somevalue'])) {
$where .= 'column_name = ?';
$values[] = sanitizeString($_POST['somevalue]);
}
I've also used positional parameters which assumes you will be using the PDO or MySQLi libraries for querying.
No, you are using = operator, that only compares 2 values. In your case it will search for '.*' - and fail. If you want to ignore the fields, that were not filled, just don't put them into the query: no need for regexps. So, if the weapon and category are missing, your query should be like this
$searchstring = 'SELECT buildname,weapon,category,id,author FROM weapons WHERE ';
$fields = array('buildname', 'weapon', 'category', 'id');
$data = array();
foreach($fields as $value)
{
if (isset($_POST[$value]) && ($_POST[$value] != "") )
{
$data[] = sanitizeString($_POST[$value]);
}
}
$n = count($data);
if($n > 0)
{
$searchstring .= implode(' AND ', $data);
//do MySQL request and output result
}
Don't overcomplicate simple things. Also your code is vulnerable to SQL injection as some fields are not escaped.
You can do it like this:
$fields = array('buildname', 'weapon', 'category', 'id');
$sql = 'SELECT buildname, weapon, category, id, author FROM weapons';
$prefix = ' WHERE ';
foreach ($fields as $field) {
if (isset($_POST[$field]) && strlen($_POST[$field])>1) {
$sql .= $prefix . $field . '=\''
. sanitizeString($_POST[$field]) . '\'';
$prefix = ' AND ';
}
}
if ($prefix == ' AND ') {
// send the query
}
Notice: if you want to perform search with incomplete values, you could use LIKE instead of =, example:
$sql .= $prefix . $field . ' LIKE \'%' . sanitizeString($_POST[$field]) . '%\'';
But keep in mind that LIKE is slower than =
My SQL query below won't output the $srchRegion && $srchCategory string if there are $_POST values for both. Why?
if (($srchRegion!='00') || ($srchRegion!='') && ($srchCategory=='00') || ($srchCategory=='')) {
return $query .= "AND region='$srchRegion'";
} elseif (($srchRegion=='00') || ($srchRegion=='') && ($srchCategory!='00') || ($srchCategory!='')) {
return $query .= "AND category='$srchCategory'";
} elseif (($srchRegion!='00') || ($srchRegion!='') && ($srchCategory!='00') || ($srchCategory!='')) {
return $query .= "AND region='$srchRegion' AND category='$srchCategory'";
}
Is there a better way of doing this?
Instead of looking for all possible boolean values and cluttered if-else, why just keep on appending the where clause based on corresponding value populated.
if($srchRegion != '00' && $srchRegion != '')
$query .= " AND region='$srchRegion'";
if($srchCategory != '00' && $srchCategory != '')
$query .= " AND category='$srchCategory'";
return $query;
So $query acts as query builder and it keeps on adding where clause based on $_POST values being set.
Try this:
if(($srchRegion!='00' || $srchRegion!='') && ($srchCategory=='00' || $srchCategory=='')){
return $query .= "AND region='$srchRegion'";
} elseif(($srchRegion=='00' || $srchRegion=='') && ($srchCategory!='00' || $srchCategory!='')){
return $query .= "AND category='$srchCategory'";
} elseif($srchRegion!='00' || $srchRegion!='') && ($srchCategory!='00' || $srchCategory!='')){
return $query .= "AND region='$srchRegion' AND category='$srchCategory'";
}
You haven't structured the if condition right. You check two OR conditions with one AND condition, so you'll need to put the OR conditions in brackets.
I've created some if / else statements to get name from url like http://website.com/page.php?name=Love It seems to look good and trows no errors, but for some reason I am not getting data from the database. Basically it gets 'name' from url and checks of it is one of allowed categories, if yes it selects article from database that has st_category = to what user selected.
But than again for some reason it doesn't work.
Here is a snippet of code that I think causes the problem.
<?php
$category = preg_replace('#[^a-z]#i', '', $_GET["name"]);
if ($category = "Love") {
$st_category = "Love";
}
else if ($category = "Work") {
$st_category = "Work";
}
else if ($category = "Money") {
$st_category = "Money";
}
else if ($category = "Kids") {
$st_category = "Kids";
}
else if ($category = "Health") {
$st_category = "Health";
}
else if ($category = "Friends") {
$st_category = "Friends";
}
else if ($category = "Education") {
$st_category = "Education";
}
else if ($category = "Other") {
$st_category = "Other";
}
else {
header("Location: http://www.inelmo.com/");
exit;
}
$sql = mysql_query("SELECT * FROM stories WHERE showing = 1 AND st_category = '$st_category' ORDER BY st_date DESC LIMIT 10") or die (mysql_error("There was an error in connection"));
//And another stuff here to display article
?>
= is not the same as ==. In your if statements you are doing assignments not comparison.
if ($category = "Love") should be changed to if ($category == "Love") (or to if ($category === "Love") and so on...
That could be tidied up to much less code, much more maintainable, using in_array().
$categories = array(
'Love',
'Work',
'Money',
'Kids',
'Health',
'Friends',
'Education',
'Other'
);
$category = preg_replace('#[^a-z]#i', '', $_GET["name"]);
if (!in_array($category, $categories)) {
header("Location: http://www.inelmo.com/");
exit;
}
$sql = mysql_query("SELECT * FROM stories WHERE showing = 1 AND st_category = '$category' ORDER BY st_date DESC LIMIT 10") or die (mysql_error("There was an error in connection"));
And this also fixes the problem that #matino rightly pointed out, which is that you were assigning and not comparing.
You have used a single "=" in every if.
The correct syntax is with "==" or "===", like:
<?php
$category = preg_replace('#[^a-z]#i', '', $_GET["name"]);
if ($category == "Love") {
$st_category = "Love";
}
else if ($category == "Work") {
$st_category = "Work";
}
...
?>
Please use double equal sign like
if($foo=="foo1")
In your if-statements you used the = while you had to used the == sign. With the = you assign a value to a variable on the left, like $sum = 1 + 2; you wanted is $sum==3.