I'm working on paginating some data with Ajax requests. When one of the page number buttons is pressed it will send a request to a separate file to generate the next page in a table.
On my main page I'll have something like:
$query = "Select * from table WHERE field = 'something' LIMIT 5";
$result = mysqli_query($con, $query);
$row = mysqli_fetch_assoc($result);
// dump results as table
When I write the script to create a new xmlhttp request object to my "paginate.php" file, how can I carry this same query over to the file since it may dynamically change based on user input?
I was thinking of just passing the whole query string as a function parameter via a POST request, but am wondering if there is a more efficient way of doing this.
I was thinking of just passing the whole query string as a function
parameter via a POST request
Definitely do not do this! It's really really bad security practice to let the browser (ie. user) run queries directly against your database. I made this mistake in early days and my site got 0wned in no time.
Your PHP file should accept parameters, validate them, then use them to run the query
1. You XHR object sends: page_number=5
2. Your PHP validates the input and dynamically builds the query:
//set page to 1 if none was provided.
$pg = isset($_POST['page_number'])? (int)$_POST['page_number']: 1;
$pg = max(1,$pg); // lowest allowed pg number is 1
Once you have the page number, and you are sure it's an integer (not some nefarious SQL command that a user sent to your server), you can use it in your query:
$size = 5; //# of results per page
$start = ($pg-1) * 5;
$query = "SELECT * from myTable WHERE field='something' LIMIT $start,$size";
Note that if the field value something comes from the user, you don't want to include it in the query directly (this goes for any user-supplied value). Instead, you should use prepared statements and parameterized queries
Resource: https://www.owasp.org/index.php/SQL_Injection
Related
I'm creating FusionCharts with data from my database. It works if I set a static where-condition with a variable set in the code ($kommunenr = '3001';). But I would like the user of the website to choose which data the chart is based on, by inserting a number in a form field, i.e. 3018. So the value of the variable should come from the user's choice. But when I test the variable seems empty.
My code is based on these tutorials:
https://www.fusioncharts.com/dev/using-with-server-side-languages/tutorials/php-mysql-charts
https://www.youtube.com/watch?v=nqavhILvBVU
https://a1websitepro.com/jquery-ajax-form-submit-with-php-processing/2/
I have the following files:
valginfo.php (the main page)
skjema.js (get the data (the number) from the form on the main page)
chart_sample.php (lists the data from the database)
app.js (creates the chart)
I have tried to find the error by both posting the content from chart_sample.php in a div on the mainpage, and in an iframe. And of course googling.
My query in my chart-data.php (choosing the data to use in making the chart):
$query = "SELECT * FROM valg19_kommune WHERE kommunenr = $kommunenr AND kandidatnr = 1 ORDER BY kommunenr, sortering, kandidatnr LIMIT 500";
It works if the variable is static, set like this:
$kommunenr = '3001';
But when I set the variable like this, it looks empty:
$nr=$_POST['nr1'];
$kommunenr=$nr;
I expect the posted number to be stored as the value of the variable and beeing part of the query, but it is not. When I echo the query and the result from chart_sample.php into a div on the main page, I looks perfect:
SELECT * FROM valg19_kommune WHERE kommunenr = 3018 AND kandidatnr = 1 ORDER BY kommunenr, sortering, kandidatnr LIMIT 500
[{"label":"Fremskrittspartiet","value":"42","color":"#000099","tooltext":"Elisabeth Stene"},{"label":"H\u00f8yre","value":"64","color":"#3366ff","tooltext":"Benedicte Dyvik"},{"label":"Kristelig Folkeparti","value":"56","color":"#ffff00","tooltext":"Brynjar H\u00f8idebraaten"},{"label":"Senterpartiet","value":"45","color":"#00cc00","tooltext":"Reidar Kaabbel"},{"label":"Arbeiderpartiet","value":"44","color":"#ff3300","tooltext":"Kai Guttulsr\u00f8d"},{"label":"SV - Sosialistisk Venstreparti","value":"39","color":"#ff4d4d","tooltext":"Tore Andersen"},{"label":"R\u00f8dt","value":"37","color":"#cc0000","tooltext":"Martin Werner Olsen"}]
But in my iFrame this is displayed:
SELECT * FROM valg19_kommune WHERE kommunenr = AND kandidatnr = 1 ORDER BY kommunenr, sortering, kandidatnr LIMIT 500[]
The iframe content is not updated when I submit the number.
How can I make sure the chart is made based on the number entered by the user?
Before I enter a number in the form field
After I entered the number
If I set the variable as this $kommunenr = '3001'; and remove the echo og the query.
Now I feel really stupid! I should use sessions and globals!
Start each page with session_start(); and first set and then use the global variables:
$_SESSION["kommunenr"] = $kommunenr;
$kommunenr = $_SESSION["kommunenr"];
This question already has answers here:
PHP Session + MySQL resource
(2 answers)
Closed 6 years ago.
I am setting up a paging with my web page. I have a resource containing a big result set, created as follows:
$sql = "select * from some_table";
pg_prepare($connection,"list",$sql);
$result = pg_execute($connection,"list",array());
$_SESSION['resultSet']=$result;
Theoretically, this would store the resource of the database result set in the SESSION and I could, using pointers, go select out the "next 25 rows" and then "the next 25 rows" using an ajax call.
Now, for some reason this resource stored in the session gets stored as a integer with the value of zero (in other words false).
So when I call this code (using AJAX):
$increment = 25;
$array = array();
$i = 0;
while ($i<$amount) {
$row = pg_fetch_array($_SESSION['resultSet'],null,PGSQL_ASSOC);
array_push($array,$row);
$i++;
}
echo json_encode($array);
I get an error saying that the resource fed into the pg_fetch_array function is an integer value.
Does anybody have any ideas how to properly implement such an idea?
Thank you.
You definitely don't want to store the resultset in your session and pull pages from the session. This is why you have the database.
What you want to do is keep track of your pagination data in your javascript code (which initially it might come from PHP). Then when you fire ajax requests make sure that you are passing pagination data (current page number, number of results per page) to your server side script. Your server side script is then responsible for sending the correct LIMIT's to your DBMS (database server).
I got a Index page on which search page is included, and when I submit it, it passes values to find.php through action and method post. The code is below
if($_POST['searchsubmit']=="Search"){
$cat=$_POST['searchcategory'];
$area=$_POST['searcharea'];
$term=$_POST['searchbox'];
}
The above code is written on find.php, Now when I try to implement paging through basic paging method with where conditions to make appropiate search query
$where="where approved='yes'";
if($term!=""){
$where.=" and name like '%$term%'";
}
if($cat!=""){
$where.=" and category like '%$cat%'";
}
if($area!=""){
$where.=" and area like '%$area%'";
}
$start=0;
$end=5;
if($_GET['page']!="")
{
$start=$_GET['page']*$end;
}
Where $start is my initial limit, and $end is my number of records. For the first page of paging, I pass a variable page with 0 for first page
First
and my search query now becomes
$que="select * from shops ".$where." ORDER BY likes DESC limit $start,$end";
As soon as I click on "first", My new link become "/find.php?page=0"
and the post values which I recivied from index page search bar are lost.
Is there any way to retain those values ?The two methods which I though are sending them again through url with GET, or the other way is to store them in session.
Is there any third method available ?
Marc is absolutely right. Do not use the code as it is.
As an alternate solution to your problem -
Your page index.php (search form) submits to itself
Assemble your search query as querystring in index.php if its a post
Redirect to find.php with the assembled querystring
Every search information will always be in the querystring.
Use your pagination happily.
The comments are correct.
Use:
// Start the session
session_start();
// Save variables into session
$_SESSION['somevalue'] = $_POST['value'];
Then when any page calls session_start it will have access to $_SESSION['somevalue']
Also, you are wide open for SQL injection. Sanitize your values to ensure no one can put arbitrary sql code into the string. if you are using mysqli it should as simple as this:
// After connecting to the DB
$_POST['somevalue' = $mysqli->real_escape_string($_POST['somevalue']);
Then be sure to hardcode quotes around string values like you are doing.
If you want to be safer you can use prepared statement instead.
Hope this helps.
I have a PHP results page which starts off "first-pass" with ALL rows returned. It's a search listing of all pizza places in the county.
SELECT * from pizzeria;
Then the user can drill down into more detail... the page also has a CSS dropdown menu where the user can pick a specific neighborhood (which carries a URL):
href="samepage.php?neighborhood=HELLSKITCHEN"
which then changes the query after I pick up the $_GET[]
SELECT * from pizzaria WHERE nbh=(the $_GET[] variable sent in the URL);
but I'd like the page to call itself and I have header("Cache-Control:no-cache"); at the top.
I'm trying to create a first-pass or first visit flag variable with the isnull() function:
if (is_null($firstpass)) {
$query = SELECT all the records from the pizzaria table
} else {
$query = SELECT only the records WHERE I $_GET[] the value from the reloaded URL
}
It seems though that the $firstpass variable doesn't stick on reloads. Should I SESSION that variable? (though still have the problem of constantly resetting it)
Or maybe implement some other approach?
I know I can redirect to a separate second page and javascript back to this page to avoid "headers already sent", but I want to avoid the round-trip back to the client.
Is there a known best practice on reloads with new info? Kinda new to PHP here. thanks
Maybe I didn't understand well your problem but why wouldn't you do :
if (!isset($_GET['example'])) {
$query = 'SELECT * FROM pizzerias';
} else {
$query = 'SELECT * FROM pizzerias WHERE pizzeria = \'.mysql_real_escape_string($_GET['example']).\' LIMIT 1';
}
at the first pass because, it seem that the $_GET variable is set only when the user choose a pizzeria?
Here is a more targeted answer.
NOTICE: mysql_* functions are being depreciated, so use PDO instead. In my example I'm being semi-lazy and not using PDO.
//Connect to database and define table up here
...
if(!isset($_GET['neighborhood')){
$q = "SELECT * FROM pizzeria;";
}else{
$q = sprintf("SELECT * FROM pizzeria WHERE nbh=%s",mysql_real_escape_string($_GET['neighborhood']));
}
$query = mysql_query($q);
foreach($row = mysql_fetch_array($query,MYSQL_ASSOC){
//display the updated view of restaurants.
}
I would also suggest that you use jQuery for that Web 2.0 effect. It's really nice when you select from a drop-down menu and things magically move without a page reload.
I was wondering how to do the following best with PHP/MySQL and jQuery:
There is a basic search mask where you enter a city and a from-to-date. You process to the search-result page, where you then can narrow your search results with certain parameters (checkboxes, jQuery slider, text-input, ...). The search-results should then update on the fly without the whole page being reloaded...
I manage to use jQuery ajax and load to send information to another php file, perform e.g. a SELECT and return the results to the search detail page, but I don't know how to combine different changes that narrow the search results.
Furthermore, there are already results on the detail page, so I do not need to add more results but "delete" the results that do not fit anymore...
The thing is that each parameter to narrow the search is connected to another table in the database. Do I have to and how do I add joins to the original query...? Or am I thinking in the wrong direction?
Yes, this is absolutely the right direction. Use
$(document).ready(function() {
$('#ID_OF_YOUR_ELEMENT_TO_LOAD_INTO').load("load.php?parameter1=<?php echo $parameter1; ?>¶meter2=<?php echo $parameter2; ?>");
});
to get the results when the user gets on the page for the first time, to get the results according to your city and your dates.
Check in the load.php which parameters are set and use the ones that are set to build your query. Then, when the form (or forms, depending) are updated, you have to use .load again, like this:
$('#ID_OF_YOUR_FORM_BEING_UPDATED').change(function() {
$('#ID_OF_YOUR_ELEMENT_TO_LOAD_INTO').load("load.php?parameter1=<?php echo $parameter1; ?>¶meter2=<?php echo $parameter2; ?>¶meter3=<?php echo $parameter3; ?>");
});
Get the initial tuples via PHP/MySQL, save them into some Javascript structure and create the html needed to display the data with javascript from this structure.
Any time you want to filter the data you rewrite the html and check the filter condition on the fly, e.g. don't write tuples from the structure that don't match your filter condition.
You can see who this is done at http://www.wowhead.com
This is of course just one way. ;-)
You could always write some code to generate an SQL query based on passed arguments.
You ajax could query the page with a bunch of arguments in addition to your basic city and from-to date based on what the user has selected. If your page preserves the previous search options selected, it should be able to just let the user add on more options and keep processing them in the same way. Your php would then test to see if the arguments are set in the $_POST or $_GET variable ($_POST is more secure for ajax generally, but my example will use $_GET for simplicity) and build the query like that.
Example:
Javascript generates a query like searchAjaxHandler.php?city=Chicago&from=2012-03-01&to=2012-03-05&someColumnLowerRange=500&someColumnUpperRange=700
Your php script then processes as follows:
$query = "SELECT * FROM Data WHERE City=? AND Date > ? AND Date < ?";
$arguments = array($_GET['city'], $_GET['from'], $_GET['to']);
if (isset($_GET['someColumnLowerRange'])) {
$query .= " AND someColumn > ?";
$arguments[] = $_GET['someColumnLowerRange'];
}
if (isset($_GET['someColumnUpperRange'])) {
$query .= " AND someColumn < ?";
$arguments[] = $_GET['someColumnUpperRange'];
}
//execute the query
//using PDOs (google them...they are a good way to prevent sql injection and
//support multiple database types without modifying code too much), create a
//statement with the above query in put the statement in $statement
$statement->execute($arguments); //this uses the $arguments array to fill in the prepared statement's ?'s
//then do the stuff to get the retrieved rows out of the result returned
After all that, the javascript side would just to the same thing you were doing before by replacing all the previous results with the results that you got back.