I have created a very simple CRUD that queries my database for Hotel details and displays them within an HTML table.
By default my mysql query returns the Hotels in the order they were created. I have come up with a few different sql statements to return results by distance or A-Z and I would like the user to select which they prefer.
How can I create a simple dropdown with for example "Name" and "Distance", which when selected will reload the page using the correct sort query using PHP?
Your basic structure is going to look like;
HTML;
<SELECT id="sort_select" onchange="javascript:re_sort();">
//options
</SELECT>
Javascript function;
function re_sort() {
//make ajax call using sort_select value
//refresh table contents
}
PHP;
if($_GET['sort_field'] == 'fish') {
//execute fish sort sql
}
else if($_GET['sort_field'] == 'goat') {
//execute goat sort sql
}
//return response
Do Not use the $_GET value directly in the sql query, instead use the structure above.
Sounds simple enough. You add an ORDER BY clause populated by the value from the dropdown.
Fair Warning!
Direct user input is highly dangerous! And prepared statements cannot be used on an ORDER BY value. You'll need very aggressive whitelisting, make sure the value you receive is one of pre-defined values, which are fetched from somewhere on the server (the database schema, or hardcoded into the PHP code).
Never let user input arrive your query unchecked and unsanitized!
More information about SQL Injection.
You will need to use JavaScript that handles the change event and reload event. However, you will want to handle disabled JavaScript browsers too. You can do that by maybe showing a sumbit button and hiding it with the JavaScript.
As far as PHP there are several ways to approach it, but here is an idea. Store the sorting values into an array. Then have the index be a number, just so SQL injection will not take place if done right as we do not want to allow pure SQL statements. When the user changes submit it.
In the code have a switch and append the appropriate SQL statement to it based on the number input.
Related
I'm making a website for renting a car using PHP and MySQL .But I'm stuck, because I don't know how to combine car details and booking form details and show it in PHPMyAdmin when user submits the form.
Representation
You need to create relational representation in your MySQL database, like a table for cars, of the like of
cars(id, ...)
Where the ... represents whatever details you intend to store.
Storing a car
You need to create a PHP script that takes car details as input and stores cars as output. Since you already told us that you have a form, you will most likely use $_POST (an array with your named form elements for the form that you have submitted) as the input, but it is strongly recommended that you separate your functionality part from the definition of your input. So, you will most likely have a function/method (a standalone function or a method of a class) that will look something like this:
function storeCar($input) {
//...
}
where $input is an associative array and you actually store the values. Of course, pay attention to SQL injection and XSS injection as possibilities. These are possible vulnerabilities that infest the codes of most beginners. You can used parameterized queries to prevent SQL injection and htmlspecialchars to protect against XSS injection.
Your code will end up executing an insert into ... type of command once you POST your form.
Loading cars
You can execute select * from cars to see what your cars' details are (but it's better to list only the columns you are interested about) at any places that are connected to MySQL, including PHPMyAdmin. Or, in some UIs, such as PHPMyAdmin you can click on table names.
This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 3 years ago.
I asked this question earlier Preventing SQL Injection in dynamical SQL, but was not clear which resulted in the question being closed, and was later told in the comments that I should ask the question again.
A requirement of my PHP/MySQL application is to allow all users to create their own multiple "views" of the data. These views are not traditional SQL views, but performed by the application.
For instance, the user could create a view and provide the following criteria:
Name of the view.
Desired records per page.
Which columns to display by using a dropdown menu.
Any filters for the results. A first dropdown menu is used to select the column, a second dropdown menu is used to select the operator (equals, not equal, greater than, etc), and then either a third dropdown menu is used to select the value to be matched or the user directly enters the value to be matched.
Whether the records should be grouped on a given column.
Based on the user's selection, various tables might need to be joined to the query to support the select, where, and group by clauses, and the application is used to eliminate duplicate table joins should they exist.
After the user has finished configuring their views, there is a dropdown menu which allows them to select their desired view, and the appropriate results are displayed.
I have implemented this functionality by storing the user's selections in several tables, and also storing the resultant query (actually, I store individual sections of the query in various columns so I may count the total results in an initial query and return the correct number of results in a second query) in a SQL table. Note that I am storing the user's selections only so that I can allow them to edit their view requirements, and not to create the resultant query on the fly (more on this later).
I recognize that I have to be very careful as doing this can be prone to SQL injunction. For instance, I can't just escape the user's input using PDO and store it in the database, and then later retrieve the data and use it in a query since when it is retrieved, it is no longer escaped.
To combat this risk, I limit user input to integers wherever possible, and typecast them where possible. Where user inputs are percents and dollars, I multiply by 100, typecast the resultant as an integer, and then divide by 100 before storing it. A couple of the filters require text as the value in the WHERE clause, and as stated earlier, escaping the data is not enought, and instead I am using $user_input= preg_replace('/[^a-z0-9,]/i', '', $_POST['user_input']); to make safe.
Is this an accepted method to implement this functionality? Is there an easier way to ensure the user input is safe? My earlier post Preventing SQL Injection in dynamical SQL indicated that this type of practice should never be attempted, however, I don't know how else to do it. Are there any other steps I should take to prevent injection?
Or maybe I should not create a query and store it in a table when the user saves his view configuration, but create the query on the fly using the user's saved values each time the user selects a given view. This would have a negative performance impact and add complicity but I suppose I can do it. Would you recommend using this strategy?
Thank you
Hello I get you I think.
This is what you are looking for:
http://www.php.net/manual/en/function.addslashes.php
$safestring=mysql_real_escape_string($_POST['user_input']);
$safestring=addslashes($safestring);
If you want to make it even more safer, that is the user cannot input html in the input,
use this function after using the above one (i.e. mysql_real_escape_string)
$safestring=htmlspecialchars($safestring);
Now all your use input will stay as it is,
if string is "user's input" it will stay as "user's input" and not change to "users input", so nothing is being replaced, and its still safe.
Regards.
I'm developing a basic php based function that executes MySQL queries in order to sort the data in the database and present it to the user. As a general statement, is it considered best practice to simply construct static queries and to execute them as needed, or simply piece together elements of a MySQL statement based on conditions?
To narrow the question, I have a specific example:
Say I have a few drop-down menus that define the search on the user's end. Let one drop-down simply contain a list of names, say Bob Smith, and the two others a date range. From there, I can easily create a search along the lines of SELECT item FROM checkOUT WHERE... I can definitely write a general query with parameters to be executed when ALL three of the parameters are present. Consider the case when only a date range is selected regardless of individuals - that would require only two parameters and a different general query. And what if the data is spread across multiple tables? That has to be taken into account. I should add as well that my function is based on drop-down menus - not original user input.
Basically, what would be the best method to create the MySQL Query - prepared statements or dynamically created statements? Obviously, the end result will rely on a hybrid of the two, but to which side it leans the farthest is the issue. I'm asking this question as I am not too familiar with this particular side of handling multiple queries from one source. Typically, I simply have to execute one query to get what I need and work with it - not sorting.
Any insight is appreciated.
I usually make a $where variable and an $order variable and then build them based on the filter input from the page. Then i just append that to the base $sql variable and run it. Seems to work great for me. Just don't forget to escape any nasty input from the user before running the query though.
I've searched this relentlessly and I cannot find an answer to my quandary - I think the problem is that I'm not exactly sure WHAT to search for! Anyhow, my problem is this...
Scenario:
Imagine having a database of, for arguments sake, recipes and you wanted to give users the ability to generate a list of recipe suggestions based on various criteria.
In the form of a web page, I would want this to be a series of drop down boxes on the left. The user would select their filter options from the drop down boxes and, after pressing the submit button, would be presented with a list of recipes that fit the criteria.
So they could, for example select 'Meal Type', 'Calories', 'Cooking Time' and then (after hitting submit) get back a list of recipe suggestions that fit the bill.
(Ideally they would appear without the need for reloading the page and would be contained within a slider to browse through, but I can probably crack that part if I get the underlying part sorted...)
Requirement:
I just need to know - at a top level - which technologies I would use to achieve this (and the process of how they work together).
I'm guessing I'd need a MySQL dB with recipes that are tagged with criteria, then use the form and php to pull from the database. Is this correct?!
Seems like such a common requirement, but I can find no good reading on how to achieve this..
Take a look at the PHP guide to prepared statements. You'll be basically writing a select statement against the table where your data resides, with the where clause of the select statement being the parameters selected by your user in the form.
PHP Prepared Statements
The reason you want to stick to prepared statements is that they are generally more secure against attacks on your site via the form, using SQL injection.
For the end to end solution, your front end will submit to a PHP page which will then handle the criteria specified by the user, translating those into the prepared statement which will find the data from your table. The table itself will need to have columns which correspond to the criteria. That gets more into database design which is a much larger topic to cover here, however there are plenty of guides out there for that.
Really you want to break the solution down into the subcomponents, then find various guides out there to tackle the parts. Good luck, hope this helps. :)
The process:
1) User makes selection and clicks submit button. That will initiate a HTTP POST to a PHP page (can be the same PHP page) where you would collect these information.
2) Open a MySql database connection with PHP. You would need to know SQL to pull data from MySql DB. Depending on how your database schema is laid out.
3) Once you pull this information display them as a checkbox where user can click.
This is the bare minimum.
If you wanna get a bit more fancy you can use JQuery ajax post (http://api.jquery.com/jQuery.post/) so the page does not refresh.
Good luck and I'm already hungry. haha.
When the user selects options in your form and submits it, this will run a PHP script on the server. The server retrieves the option parameters, and uses them to construct a SQL query. For instance, the script might contain something like:
$criteria = array();
if (isset($_POST['calories'])) {
$criteria[] = 'calories < '.$_POST['calories']);
}
if (isset($_POST['time'])) {
$criteria[] = 'cooking_time < '.$_POST['time']);
}
...
$query = 'SELECT * FROM recipes WHERE '.implode(' AND ', $criteria);
You use a library like mysqli or PDO to perform the query and get the results. Then you loop through the results, and format them into an HTML table which will be returned to the user as the resulting web page.
Or the PHP script could return the results as JSON data. Your web page could use AJAX to get this data from the server, then use JavaScript to format it into a table.
Basically I'm looking to create a page using PHP that will take SQL input, and output the results returned by the DB (MySQL). This is not for a production website (I understand the security implications). It's more for learning and practice. Kind of like the SQL console section of phpMyAdmin, or even similar to what sqlzoo.net can do (I think they are using perl, but I'd like to do it in PHP). Is there a practical way to accomplish this?
For example, how can I create a page in PHP/HTML to display a table of results when I don't know how many columns the query will return?
Also, what is the most practical way to allow a visitor to this web page to restore the DB to a default state with the original data? (e.g. create a sql dump of the original state and make a button that runs it? or is there a better way?)
Thanks!
Use * in your SQL query to fetch all columns and loop over the results from mysql_fetch_row() or mysql_fetch_assoc() with foreach.
Besides that, have you thought of using the mysql CLI ? It's useful for those requirements.
This question should be more specific than it is now.
"create a sql dump of the original state and make a button that runs it?" - Yes. But make sure you drop/delete the existing data.
You may have to run at least two queries... first return one row using LIMIT 1, and count the returning elements (using PHP count($row) if you use mysql $row = fetch_row($handle) ) to count the columns, and you can use SQL COUNT() to find out how many rows would be returned.
As for returning data to original state, I think a drop/recreation from a dump like you said may be the simplest and most reliable option.
Your best option is just running the query, checking if the amount of rows > 0, and then if it is, loop through the query resultset in a foreach and just show whatever you like.