The below code displays data from a table and then filters it depending on the results of two combo boxes. I am able to order the results by ID once the form is submitted, but not on initial load (where all are listed). I have tried $sql = "SELECT * FROM Places ORDER BY ID"; which works when the list loads but returns an error when the form is submitted. Hope that makes sense. Any ideas? Thanks!
// Default query
$sql = "SELECT * FROM Places";
// check if form was submitted
if (isset($_POST['area'])) {
$connector = 'where';
if ($_POST['area'] != 'All') {
$sql .= " where Area = '".$_POST['area']."' ORDER BY ID";
$connector = 'and';
}
if ($_POST['theme'] != 'All') {
$sql .= " $connector Theme = '".$_POST['theme']."' OR Theme2 = '".$_POST['theme']."'
ORDER BY ID";
}
}
Your ORDER BY ID clause must appear at the very end of your statement. If both $_POST['area'] and $_POST['theme'] are filled, you end up with a query like this:
SELECT ... WHERE Area = 'some area' ORDER BY ID AND Theme = 'some theme'
Add the ORDER BY bit as the last part of your query.
I think you are missing a default behavior statement. I.e. Your IF statement doesn't have an else clause. So you are checking for isset and if it is change the select query, but there is nothing to say IF ! isset SELECT query should be .... ORDER BY ID.
Also I would try echoing your SQL queries out each time you set / change a portion of it to understand exactly what is being sent to the DB.
Lastly I always check the mysql.general_log table for the last run queries to see what is actually happening at the DB end.
It looks like it is possible for $_POST['area'] != 'All' and $_POST['theme'] != 'All'. In that case you will be putting the ORDER BY clause in twice. That probably your problem.
So try this.
// Default query
$sql = "SELECT * FROM Places";
// check if form was submitted
if (isset($_POST['area'])) {
$connector = 'where';
if ($_POST['area'] != 'All') {
$sql .= " where Area = '".$_POST['area']."'";
$connector = 'and';
}
if ($_POST['theme'] != 'All') {
$sql .= " $connector Theme = '".$_POST['theme']."' OR Theme2 = '".$_POST['theme'] . "'";
}
if ( $_POST['area'] != 'All' || $_POST['theme'] != 'All' ) {
$sql .= ' ORDER BY ID';
}
}
Thanks for all your help, I have solved the problem at the server end anyway so no need for code. Thanks for bringing attention to the security issues, I had these in the back of my mind but wasn't sure how bad it was! If I change the code to PDO would it help greatly? I have already reduced the privileges of the user to minimal. Thanks again.
Related
Anyone who can help on how to apply MariaDB: IF-THEN-ELSE Statement in PHP.
I want to query when the account type is Admin and he/she created the data in pre_registered table the Cancelled status also display in the list but if he/she is Admin but not the on who created the data it will not display on the list. If normal user is logged in the system, the Cancelled status will not be included in the list.
I have try the below query but did not work.
<?php
$account_type = getActiveAccountType($connect);
$query = "SELECT * FROM pre_registered WHERE ";
if ($account_type == 'Admin') {
$query .= "
IF registered_created_by != ".$_SESSION['account_id']." THEN
{
registered_status != 'Cancelled'
}
END IF;
";
} else if ($account_type == 'User') {
$query .= "
registered_status != 'Cancelled'
";
}
You want registered_status != 'Cancelled' in regardless of the user type, so include this in $query.
For the admin user, you want to include results with registered_created_by = $account_id. So in this PHP if branch. Because its an OR condition, it will be included regardless of the registered_status.
$query .= ' OR registered_created_by = ?'
When executing this query as a prepared query, pass $_SESSION['account_id'] as the value to be used in the query.
I am new to programming as well, but I hope this helps.
Try getting the results first and write a condition that checks if registered_created_by == $_SESSION['account_id'], then show the column if it does and hide if it doesnt.
I'm trying to create a dynamic search query, based on the user input.
Requirements:
A user could fill in none, some, or all fields.
The query searches in a table for a record that matches all the requirements.
Now I have done my research, and I found out multiple ways on doing this. But none of them work, and if they do, they are far from practical.
Attempt:
At the moment I'm creating a query like this:
SELECT *
FROM assignments
WHERE (id = $id OR id = '')
AND (field1 = $field1 OR field1 = '')
This query works, but only if you fill in all the fields.
I got this from a stackoverflow article, that I can't find anymore, that said:
If the user has filled in an input field it will check the first rule
"id = $input"
and if the user hasn't specified any input it will check for "id = '' " and when it
checks for that, it will just return everything. Because it escapes the empty search rule.
But as you might already know, it doesnt work..
How would you suggest me to approach this?
Try getting all of the post vars and looping through them to see if they are valid, and then build your query
<?php
$id = $_POST[id];
$field1 = $_POST[field1];
$field2 = $_POST[field2];
$field3 = $_POST[field3];
$whereArr = array();
if($id != "") $whereArr[] = "id = {$id}";
if($field1 != "") $whereArr[] = "field1 = {$field1}";
if($field2 != "") $whereArr[] = "field2 = {$field2}";
if($field3 != "") $whereArr[] = "field3 = {$field3}";
$whereStr = implode(" AND ", $whereArr);
$query = "Select * from assignments WHERE {$whereStr}";
Something like that should handle what you need
You should start with a string like yours up to the WHERE statement, then after that you loop through all the fields the user wants to search with and add them to an array, then use the PHP function "implode" to glue the fields together with an AND statement as "glue".
Now add on the glued string to the startquery and voila!
I'd give example but on phone atm!
Building the query dynamically based on the responses is definitely a must. But another nice feature that allows users to find results based on even partial responses is using a MySQL REGEXP query. So for instance, if they wanted to find "maverick" in a Top Gun database, a query REGEXP = 'mav' | 'rick' would return results. This brings your search much closer to the search engine functionality that users are accustomed to.
Here's a REGEXP example, simplified.
I am trying to create a PHP file to help search a table built in MySQL from a webpage. I have built the form, which allows the user to enter keywords into two of the search criteria and a drop-down menu for the third. However, I am having trouble with the PHP file itself. I have appeared to do something wrong and cant quite figure out what is going wrong. If anyone can spot an error in the code below I'd really appreciate the help.
Thanks.
// define variables and set to empty values
$Location = $Commemorating = "";
if (isset($_GET['Region']) && !empty($_GET['Region']))
{
$Region_name = $_GET['Region'];
if (empty($_GET["Location"]))
{
$Location = "";
}
else
{
$Location = ($_GET["Location"]);
}
if (empty($_GET["Commemorating"]))
{
$Commemorating = "";
}
else
{
$Commemorating = ($_GET["Commemorating"]);
}
$query = "SELECT Monument,
Location,
Commemorating,
Region,
FROM MONUMENTS
WHERE Region = '$Region'";
//..if a location is specified run this query
if ($Location != "")
{
$query .= " AND Location LIKE '%$Location%'";
}
//..and if a name is entered run this query
if ($Commemorating != "")
{
$query .= " AND Commemorating LIKE '%$Commemorating%'";
}
//..and if a region is specified run this query
if ($Region != "All")
{
$query .= " AND Region LIKE '$Region'";
}
$query_run = mysql_query($query);
}
$query = "SELECT Monument,
Location,
Commemorating,
Region,
Looks like you should strip list comma in field list from the query:
$query = "SELECT Monument,
Location,
Commemorating,
Region
Like this.
There is a bit misunderstanding since you check is Region is not empty, then query for items in given Region and then add another cause in case of Region is not 'All'. So if I run your code with Region = 'All' then the query will return only the items that have Region set to 'All', which sounds a bit odd (I'd say monuments are at a single region, isn't it?).
You also use LIKE while may simple use = since you add sibgle quotes (') around strings so it won't give you any 'wildcard' match but slow down the query. Another thing to do is to do some mysql escape function to be sure you won't get SQL code in one of your GET query.
May I also suggest to short your code a bit:
$Region_name = isset($_GET['Region']) ? trim($_GET['Region']) : '';
if ($Region_name) {
$Location = isset($_GET['Location']) ? trim($_GET['Location']) : '';
$Commemorating = isset($_GET['Commemorating']) ? trim($_GET['Commemorating']) : '';
$query = sprintf("SELECT
Monument,
Location,
Commemorating,
Region
FROM MONUMENTS
WHERE 1=1%s%s%s",
$Region!='All' ? "AND Region='".mysql_real_escape_string($Region)."'",
$Location ? "AND Location='".mysql_real_escape_string($Location)."'",
$Commemorating ? "AND Region = '".mysql_real_escape_string($Region)."'",
);
...etc...
I add 1=1 so I can easily add AND to the following causes without worry.
Use $Region_name instead of $Region in your query. I see you depend on user input (via $_GET). Make sure you sanitize user input: https://stackoverflow.com/a/3126175/1071063
I need some guidance to make an advanced search script for a website I'm working on.
I already know how to search the database for simple queries. The problem I'm encountering right now is how to search, when using multiple select boxes. For example:
This is just a simple form with different search options. The question is:
The visitor can choose to search on a country or city, both or even with all three options.
How do I catch that in the PHP script? Do I have to check if for example a city has been chosen, and fire a query based on that? But if I do that I would have to make different queries based on each select option.
In pseudo-code it would be something like this: (I imagine)
if country and city and something else is not null, launch a query to search in all three tables in the database.
But what to do when just the country has been chosen? Or just the city?
Is there a simple way to accomplish this?
Thanks in advance.
I like using an array to join conditions so I don't have to worry about leading or trailing AND's.
$conditions = array();
if ($formCondition1) {
$conditions[] = 'state = "'.$somevalue.'"';
}
if ($formCondition2) {
$conditions[] = 'country = "'.$somevalue.'"';
}
...
if ($formConditionN) {
$conditions[] = 'N = "'.$somevalue.'"';
}
//finally join the conditions together, the simplest case is with ANDs (if you need to add ORs, which it sounds like you don't, then this code would be a bit more complex)
$sqlStatement = 'SELECT field1, field2 FROM tableABC WHERE '.implode(' AND ', $conditions);
EDIT: don't forget to escape the input to prevent injection attacks, and of course test to make sure there are at least 1 condition before running the query.
EDIT: lol jswolf and I think very much alike :)
I make a $where array, add my conditions to it as necessary, and then implode it with ' AND ' as the glue. So something like:
$where = array();
if $city is defined
$where[] = "city = '".mysql_real_escape_string($city)."'";
fi
if $country is defined
$where[] = "country = '".mysql_real_escape_string($country)."'";
fi
...
if(count($where)) {
$query.= ' WHERE '.implode(' AND ', $where);
}
I would try something like:
$qry = "SELECT * FROM table WHERE ";
if ($country != '') {
$qry .= "country='".mysql_real_escape_string($country)."' AND "
}
if ($city != '') {
$qry .= "city='".mysql_real_escape_string($city)."' AND "
}
$qry .= '1';
$res = mysql_query($qry);
The query is built up depending on what is set. Note the "1" on the end of the query string which is always true. This is needed to follow the "WHERE" if $country and $city are both empty, or to follow the last "AND" if they are not.
So i have this videosection, but i want to make a "sorting" option avaible for users.
Sorting Options: ALL (no WHERE in the sql statement), Videoklips (WHERE SCtry = 0), SC try (WHERE SCtry = 1)
Now, i know how to do it "my" way. I would have placed links on index.php:
?sort=video and ?sort=SCtry
Then make 2, if sort video, if sort sctry
and then duplicate the whole index.php right now(which displays everything) into the 2 if's and then just edit the SQL statement SELECT, with WHERE SCtry = '0' on ?sort=video, and WHERE SCtry = '1' on ?sort=SCtry.
Now, i KNOW how to sort out, but i want to code it in a smarter way (if it exists, of course), because this seems to be too much to duplicate the whole site and then just only change 1 line...
Example of what i ment with index.php, that i am going to duplicate:
<?php
$hent_meetup = mysql_query("SELECT * FROM member_film ORDER BY id DESC LIMIT 0,200") or die(mysql_error());
while($vis = mysql_Fetch_array($hent_meetup)) {
?>
without seeing example code, I can tell you this is an example of what I'd do.
<?
//all of the code before the SQL statement here...
$sql= ' SELECT `column` from `tablename`'; //or any other SQL that is appropriate before the conditional
if(isset($_GET['sort'])){
if($_GET['sort'] == 'video'){
$sql .= ' WHERE `SCtry` = 0';
}elseif($_GET['sort'] == 'SCtry'){
$sql .= ' WHERE `SCtry` = 1';
}
}
$sql .= ' ORDER BY `whatever`'; //or any other SQL that is appropriate after the conditional
//rest of code... no need for duplication
?>
edited as per OP request...