Been searching all over for this but cant find an answer so thought I would ask here.
I have 5 drop down 'option box' lists whose data is populated from a database. The database information is about a user selecting a computer manufacture from the first drop down list, a computer type from the second, a computer colour from the third and finally a minimum and maximum price from the fourth and fifth drop down lists.
These user selected variables are then posted to a php 'search' page and a query is run on them. My question is, if (for example) a user only selected a computer 'manufacture' and 'make' and left all the other option boxes blank, how would I run this on my SQL search? Would I need to set then 'non set' variables as wildcards?
Any help would be appreciated!
You can build your query dynamically, something like this:
$sql = "SELECT ... FROM ... WHERE 1=1 ";
if ($manufacturer != "") {
$sql .= " AND manufacturer = ...";
}
if ($computerType != "") {
$sql .= " AND computerType = ...";
}
// etc...
SELECT * FROM TABLE WHERE
COLUMN_NAME_1 = IF('".$select_result_1."'='',COLUMN_NAME_1,'".$select_result_1"') AND
COLUMN_NAME_2 = IF('".$select_result_2."'='',COLUMN_NAME_2,'".$select_result_2"') AND
COLUMN_NAME_3 = IF('".$select_result_3."'='',COLUMN_NAME_3,'".$select_result_3"') AND
COLUMN_NAME_4 = IF('".$select_result_4."'='',COLUMN_NAME_4,'".$select_result_4"') AND
COLUMN_NAME_5 = IF('".$select_result_5."'='',COLUMN_NAME_5,'".$select_result_5"');
Related
I have a HTML form that people can select some or all off to search a database for member profiles.
Some of the options are:
Male/Female
Age
Location
check boxes like intentions or interests
etc
I need to tailor a MySQL query to meet the selection the member has chosen.
I'm asking because I built a custom search like this before and it turned into a complete mess with multiple queries depending on what was selected.
Would it be best to just build one query and have parts that are added depending on what is selected?
Does anyone have a ruff example?
Database Schema:
I have a number of tables with the related information so I would need to use joins. That said everything works on one primary key PID so it would all join on this.
You could do something like this:
<?php
$whereClause = '';
if($_GET['gender'] == 'male'){
$whereClause .= ' AND gender = "M"';
}
if($_GET['age'] != ''){
$whereClause .= ' AND age = "'.$_GET['age'].'"';
}
?>
I would use an array:
$where = array();
if($_GET["gender"]!=""){
$clean = mysqli_escape_string($db, $_GET["gender"]);
array_push($where, "gender = '$clean'");
}
// etc...
$where = implode(" AND ", $where);
$sql = "SELECT * FROM table WHERE $where";
I am looking for idea to change radio to checkbox and make SQL SELECT with it:
Now The user chooses category by form radio (one category) code:
$zapytanie = $pdo->prepare('SELECT * FROM pytania_new WHERE Kategoria = :kategoria');
and the script show all questions with one category which we chose.
Now I would like to have choosing a few category, so I changed my current code to show checkbox form and save chosen category to array, but now I don't know how to do SQL which show me questions with a few category
$zapytanie = $pdo->prepare('SELECT * FROM pytania_new WHERE Kategoria = :kategoria AND :kategoria2');
this doesn't want to work.
and the next problem is how to check how much category SQL should download from database.
I hope that you help me with it :)
AND operator requires column to be mentioned, not value
So in your case Kategoria = :kategoria AND Kategoria2 = :kategoria2
But we don't have your structure, maybe you don't have second column, so you need to recieve 2 rows as a result? Then use OR operator:
Kategoria = :kategoria OR Kategoria = :kategoria2
You can do this with a simple for loop.
$categories = array("first","second");
$query = "";
$delimiter = "";
foreach($categories as $category) {
$query .= $delimiter . "kategoria = $category";
$delimiter = " OR "; //Dont really know how your sql looks but this makes more sense. Otherwise change to AND if a row can have multiple categories
}
$sql = "SELECT * FROM pytania_new WHERE $query";
OK, so on the first we have to create string with all categories like this:
$kategorie = join(',',$kategoria);
After that there is simple SQL which can find a few category in base
$zapytanie = $pdo->prepare("SELECT * FROM pytania_new WHERE Kategoria IN ($kategories)");
and it is all :)
I'm developing in php/sql a web application where users will be able to post items that they'd like to sell ( kinda like ebay ). I want non-members to be able to comment on the items or ask queries about items.
My problem is I want to display each item as well as any comment/query made about that item, in a similar manner as the way Facebook wall works.
I want to "append comments"(if any) to each item. The comments table is linked to the items table via column item_id. And the items table is linked to users table via column user_id. I have left joined users table with items table to display item details, i tried to left join comments table as well so that there are 3 joined tables.
That fails because no comments are displayed and only one item is displayed, despite there being multiple entries in each table. Here is the code i,m using.
$database->query
('
SELECT sale.*, query.*, users.id AS userid, users.username as user
FROM sale
LEFT JOIN users ON sale.user_id = users.id
LEFT JOIN query on sale.id = query.item_id
where category = "$category" ORDER BY sale.id DESC
');
$show = " "; //variable to hold items and comments
if ($database->count() == 0) {
// Show this message if there are no items
$show .= "<li class='noitems'>There are currently no items to display.</li>" ;
} else {
$show .= "<li>";
while ( $items = $database->statement->fetch(PDO::FETCH_ASSOC) )
{
$show .= "
//show item details in html
";
while( $query = $database->statement->fetch(PDO::FETCH_ASSOC) )
{
$show .= "
//show queries below item details
";
}
$show .= "</li>" ;
}
Welcome to Stackoverflow!
I recommend you taking a look at pdo. If you are already using mysql_ functions, then I recommend you switch. More on that can be found here.
Now that your pointed to the direction of to what functions to use when connecting/running queries, you now should create your tables. I use phpmyadmin for managing my database, I find it very good, but it's up to you what you use. Once you've decided on the service you use to manage your database, you should then learn how to use it by doing some google searches.
Now you need to set up your table and structure it correctly. If you say you're having items, then you should make a table called items. Next create the columns to the properties of the items. Also I recommend reading about Database Normalization, which is a key aspect of setting up your SQL tables Etc.
Once you have everything set up, you've connected to your database successfully Etc. You now need to set up the "Dynamic Page". What I mean by this is, there's only one page, say called 'dynamic', then a variable is passed to the url. These are called GET HTTP requests. Here's an example of what one would look like: http://example.com/item?id=345.
If you've noticed, you'll see the ? then the id variable defined to 345. You can GRAB this variable from the url by accessing the built in PHP array called $_GET[]. You can then type in your variable name you want to fetch into the []'s. Here's an example.
<?php
$data = $_GET['varname']; // get varname from the url
if(isnumeric($data)){ // is it totally made out of numbers?
$query = "SELECT fieldname FROM table WHERE id=:paramname";
$statement = $pdo->prepare($query); // prepare's the query
$statement->execute(array(
'paramname'=>$data // binds the parameter 'paramname' to the $data variable.
));
$result = $statement->fetch(PDO::FETCH_ASSOC); // grabs the result of the query
$result = $result['fieldname'];
echo 'varname was found in the database with the id equal to:'.$data.', and the result being: '.$result;
}
?>
So now you can see how you can grab the variable from the url and dynamically change the content with-in the page from that!
Hope this helped :)
I have made a dropdown box that is filled by a query that looks for company names from company name database, these names also have and ID number that I don't want displayed but are looked up in the query. I need the ID number to link to sites of the company so somehow when I hit the submit button on the site page it finds the ID number by looking at the position value and relating that to the position on the query array I just don't know what to do. If it helps this is how I fill the dropbox:
mysql_select_db("DB", $con);
$query = "SELECT Company_Name, ID FROM company_table";
$result = mysql_query($query) or die(mysql_error());
$options ='';
$num = 0;
while ($row=mysql_fetch_array($result)) {
$num = $num+1;
$options.= "<OPTION VALUE=\"$num\">".$row["Company_Name"];
}
<SELECT NAME=thing>
<OPTION VALUE=0>Choose
<?=$options?>
</SELECT>
Any Ideas?
There are two immediate ways this can be done. One is to keep it the way you have it using an index, $num; the other way is to use the actual company id field, ID. If you stick with the index of $num, when the user submits the form (i.e. - selects a company), you will have to re-query the database and re-loop through the results to find the specific company (or you could use a LIMIT/OFFSET; notes at end of answer).
I would recommend using the actual company id in your form:
while (($row = mysql_fetch_assoc($result))) {
$options.= '<option value="' . $row['ID'] . '">' . $row["Company_Name"] . '</option>';
}
This will generate a list of options, like you currently have, except the value of each will be the specific company id. When the user submits the form, let's assume the form is using POST, you can get the ID with:
$companyId = (isset($_POST['thing']) && is_numeric($_POST['thing'])) ? intval($_POST['thing']) : false;
$results = mysql_query('SELECT * FROM company_table WHERE ID=' . $companyId);
.. and then process as you desire.
I use $_POST['thing'] in the above example as that is what your code-example has the select field named. Also, I make the assumption that ID is an integer.
If the actual ID needs to remain hidden, as specified, the index of $num can be used with MySQL's LIMIT/OFFSET as follows:
$selectedCompany = (isset($_POST['thing']) && is_numeric($_POST['thing'])) ? intval($_POST['thing']) : -1;
if ($selectedCompany >= 0) {
$query = "SELECT Company_Name, ID FROM company_table LIMIT " . $selectedCompany . ", 1";
// process as desired
}
An option is to add a "created" field to the company table that is a timestamp, or just a 2nd column that is a random UUID column. Then set the value of the dropdown to this column so you don't show ID but you will still know the record since you are using the "other" id as well.
I actually use this method in one of my programs where it was the same situation as you, the client didn't want the ID to be shown.
If you don't want to go with this method (because you don't want a 2nd column) you could just md5 hash the ID or some other hashing method.
Then you would do
SELECT * FROM company where md5(id) = "$value".
The downside to this method is that it is an expensive query, since you won't be using an index and it has to compute all the md5 hashes for each id.
I would like the users to choose which fields they want to see and which they do not want to see.
Table: Companies(cid, cname, state, project_manager, site_supervisor, elec_engg, mech_engg, hydraulics, .....)
Note: All the columns from project_manager to the last column have the value 'Yes/No'
Lets say the user wants to find the companies that have Project managers and electrical engineers in NSW.
The Query will be:
Select cid, cname, project_manager, elec_engg
from companies
where state='NSW'
AND project_manager='Yes'
AND elec_engg ='Yes';
I was wondering how can I make this search dynamic. Displaying all job titles in a HTML form and having check boxes next to each job title and with search button. Something like below.
Query:
select cid, cname, (dynamic user input of columns)
from companies
where state="NSW"
AND Dynamic input column1 ='Yes'
and Dynamic input column2 ='Yes'
AND Dynamic input column3 ='Yes'.....
AND Dynamic input columnn ='Yes';
I'm assuming you're just ANDing all the parameters together. If you can set the name for each HTML the elements in the form exactly what you expect for the column name this should work. When you get the post back (assuming search submits the form as a post), you can loop through the post values. I'd create an array of valid columns to check against as a whitelist to avoid ever having a broken query.
Here's an example using oldschool mysql escaping or you to get the idea, but I'd really use PDO with prepared statements to populate the values of the query. The key is to protect both your where parameters and values when dynamically creating SQL. Shoot me a message if you're using PDO and would like to see that, but this will give you a place to start:
$sql = 'SELECT cid, cname, project_manager, elec_engg FROM companies ';
$whereClause = null;
//whitelist of valid where clause parameters
$validParams = array('site_supervisor', 'elec_engg', 'mech_engg', 'hydraulics');
foreach($_POST as $key=>$value){
if(array_search($key, $validParams)!==false){ //make sure you use !== and not !=
if(empty($whereClause)){
$whereClause = " WHERE ";
}else{
$whereClause .= " AND ";
}
//IMPORTANT: use whatever you're db needs to escape things or use prepare
//statement replacement
$whereClause .= "$key='".mysql_escape_string($value)."' ";
}
}
$sql = $sql.$whereClause;
echo $sql;
You can also add a loop check for just values of 'Yes' and exclude 'No' values...
As noted below in a comment mysql_escape_string($value) is bad... no doubt, to do this correctly and safely with prepared statements and pdo you would change the code to:
$sql = 'SELECT cid, cname, project_manager, elec_engg FROM companies ';
$whereClause = null;
//whitelist of valid where clause parameters
$validParams = array('site_supervisor', 'elec_engg', 'mech_engg', 'hydraulics');
foreach($_POST as $key=>$value){
if(array_search($key, $validParams)!==false){ //make sure you use !== and not !=
if(empty($whereClause)){
$whereClause = " WHERE ";
}else{
$whereClause .= " AND ";
}
//IMPORTANT: use whatever you're db needs to escape things or use prepare
//statement replacement
$whereClause .= " $key=:$key ";
}
}
$sql = $sql.$whereClause;
$db = new PDO($someDsnString);
$statement = $db->prepare($sql);
foreach($_POST as $key=>$value){
if(array_search($key, $validParams)!==false){ //make sure you use !== and not !=
$statement->bindValue(":$key", $_POST[$key]);
}
}
$statement->execute();
$result = $statement->fetchAll();
Both the prepared statements on the values and the whitelist on the parameter values will make this query safe.
just put the result of each field into a string, so something like
$builderworks = $POST_['builderworks'];
$hydrolics = $POST_['hydrolics'];
then just select from the database using all the string values, just make sure you sanitise the POST data above first using mysql_real_escape_string.
so something like
SELECT jobname FROM jobtable WHERE hydrolics='$hydrolics' AND $builderworks='$builderworks'
ect ect
so basically $builderworks etc is whatever has been POSTED in that field, it is stored inside everytime someone submits, so if fo example I went to the form, selected the field builderworks to yes, $builderworks would then equal yes when I hit submit, whatever is stored in each string is then compared using the database query then so if $builderworks has yes inside it, selecting all fields that are equal to $builderworks would select all fields equal to yes, or equal to no if I had selected no in the form.
Don't do this on your database layer. It's a really, really bad idea for security, stability and maintainability all at once. Separate your concerns. Your data access layer should not be dependent on your user's permissions and should definitely not be dependent on your view.
Extract your data from your database as you normally would (into a "model" or some other structure) and then selectively show the data of that structure in your rendering layer as needed (the "view").