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).
Related
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
I am doing this animation tool where I fetch a value from my database and then a picture will animate to a certain position. My question is if it is possible to retrieve data constantly or like every 5 seconds?
Somehow like this:
while(autoretreive){
$data = mysql_query("select * from ......");
}
UPDATED from here
Thanks for your answers! Made it a little bit clearer what to do! Maybe I can explain better what I'm doing in my code.
I am doing this animation program as said, where balls with information is moving around to different locations. I have one value that will be updated frequently in the database, lets call it 'city'.
First at previous page I post the balls of information I want based on the 'city' and I do like this (simplified):
$pid = $_POST['id'];
$pcity[0] = $_POST['city'];
$pcity[1] = $_POST['city'];
$pcity[2] = $_POST['city'];
//...
$while(autoretrieve) { // HOW TO?
$data = mysql_query(select * from table where city == $pcity[0] OR $pcity == [1] //...);
while($rows = mysql_fetch_array($data)){
$city = $rows['city'];
$id = $rows['id'];
if($city == example1){
"animate to certain pos"; //attached to image
}
else if($city == example2){
"animate to certain pos"; //attached to image
}
}
}
So for every update in the database the image will animate to a new position. So a time interval of 5 seconds would be great. I'm not an expert in coding so sorry for deprecated code. Not so familiar with AJAX either so what is going to be imported to the code? It is also important that the page is not reloading. Just the fetch from database.
you can do it with ajax and javascript
make one javascript function which contains ajax code to retrive data from database
and at your page load using setTimeout call your ajax function at every 5 second
You can use sleep function to control how often you want to fetch data.
while(autoretreive){
$data = mysql_query("select * from ......");
//output your data here, check more in link about server sent events bellow
sleep(5);
}
Since you haven't specified how you plan to access data I'm writing this answer assuming Server-Sent Events as they are only ones that make sense according to your question.
Now all this was according to your question which wasn't very clear on how do you plan to use data. Again you'll most likely want to fetch data using ajax, but Server Sent Events can also be a good way you could achieve this.
And don't use mysql_* it's deprecated, switch to PDO or mysqli_*
I have this while loop, that basically loops through a lot of records in a database, and inserts the data in another:
$q = $con1->query($users1) or die(print_r($con2->errorInfo(),1));
while($row = $q->fetch(PDO::FETCH_ASSOC)){
$q = $con2->prepare($users2);
$q->execute(array($row['id'], $row['username'])) or die(print_r($con2-errorInfo(),1));
}
(The script has been shortened for easy reading - the correct one has a much longer array)
I would like to do this more graphical, and show a progress bar on how far it has went, instead of just seeing a page loading for a few minutes (there are ~20.000 rows in this one - I have tables with much more data)
I get that you could get the total number from the old database, and I could also easily put the current number into a variable like this:
$q = $con1->query($users1) or die(print_r($con2->errorInfo(),1));
$i = 0;
while($row = $q->fetch(PDO::FETCH_ASSOC)){
$q = $con2->prepare($users2);
$q->execute(array($row['id'], $row['username'])) or die(print_r($con2-errorInfo(),1));
$i++;
}
But now I need to actually fetch $i and display it - or something like it.
How is this "easily" done?
The code for the progress bar can either be in the same document as the while loop, or in another if easier.
You can do a "master" file that does an ajax to this first file to run a single query. You could get all the entry id's in this master file, and then pass it as a parameter to the second file that does a single query. Store these ids in a javascript array.
Create a function that does this, and when the first ajax is done, move to the second element of the id array, and do another ajax with a second parameter. That's how magento imports are done by the way :)
If you need further explanations, let me know, I tried my best to explain, but may have not been perfectly clear.
// you generate this javascript array using php.
// let's say you have all the ids that have to be processed in $Ids php array.
Ids = [<?php echo implode(',', $Ids); ?>];
function doAjax(i) {
$.ajax({ // using jquery for simplicity
'url': "ajax.php?id=" + Ids[i],
}).done(function(){
if ( i >= 0 ) {
// at the point you know you're at ((Ids.length-i)/(Ids.length) * 100) percent of the script
// so you can do something like this:
// $('.progressbar').css('width', ((Ids.length-i)/(Ids.length) * 100) + '%');
doAjax(i-1);
}
});
}
doAjax(Ids.length); // starting from the last entry
So, just to explain what this does. It starts by declaring a global javascript array that has all the ids that will need to be changed.
Then I declare a recursive ajax function, this way we can make sure that only one ajax runs at any single time (so the server doesn't blow up), and we can have a fairly accurate progress. This ajax function does the following:
Sends a request to ajax.php?id=xxx - where xxx is one of the ids in the javascript array.
In the file, we get the id ($_GET['id']), you take it from the old database, and insert it in the new one. This is only for one entry.
when the ajax is done, it goes to the done() function. Since we start the doAjax() function with the last element, we do the next iteration doAjax(i-1). Since we're going backwards in the array, we check if the key is positive. If it's not, the script will stop.
That's about it.
You can't. The php is first interpreted by the server and then send to the user as HTML-Code.
The only possibility would be creating a html-page and call the php-script with AJAX.
I'm experiencing a strange problem. I'm caching the output of a query using memcache functions in a file named count.php. This file is called by an ajax every second when a user is viewing a particular page. The output is cached for 5 seconds, so within this time if there will be 5 hits to this file i expect the cached result to be returned 3-4 times atleast. However this is not happening, instead everytime a query is going to db as evidenced from a echo statement, but if the file is called from the browser directly by typing the url (like http://example.com/help/count.php) repeatedly many times within 5 seconds data is returned from cache (again evidenced from the echo statement). Below is the relevant code of count.php
mysql_connect(c_dbhost, c_dbuname, c_dbpsw) or die(mysql_error());
mysql_select_db(c_dbname) or die("Coud Not Find Database");
$product_id=$_POST['product_id'];
echo func_total_bids_count($product_id);
function func_total_bids_count($product_id)
{
$qry="select count(*) as bid_count from tbl_userbid where userbid_auction_id=".$product_id;
$row_count=func_row_count_only($qry);
return $row_count["bid_count"];
}
function func_row_count_only($qry)
{
if($_SERVER["HTTP_HOST"]!="localhost")
{
$o_cache = new Memcache;
$o_cache->connect('localhost', 11211) or die ("Could not connect to memcache");
//$key="total_bids" . md5($product_id);
$key = "KEY" . md5($qry);
$result = $o_cache->get($key);
if (!$result)
{
$qry_result = mysql_query($qry);
while($row=mysql_fetch_array($qry_result))
{
$row_count = $row;
$result = $row;
$o_cache->set($key, $result, 0, 5);
}
echo "From DB <br/>";
}
else
{
echo "From Cache <br/>";
}
$o_cache->close();
return $row_count;
}
}
I'm confused as to why when an ajax calls this file, DB is hit every second, but when the URL is typed in the browser cached data is returned. To try the URL method i just replaced $product_id with a valid number (Eg: $product_id=426 in my case). I'm not understanding whats wrong here as i expect data to be returned from cache within 5 seconds after the 1st hit. I want the data to be returned from cache. Can some one please help me understand whats happening ?
If you're using the address bar, you're doing a GET, but your code is looking for $_POST['...'], so you will end up with an invalid query. So for a start, the results using the address bar won't be what you're expecting. Is your Ajax call actually doing a POST?
Please also note that you've got a SQL injection vulnerability there. Make sure $product_id is an integer.
There are many problems with your code, first of all you always connect to the database and select a table, even if you don't need it. Second, you should check $result with !empty($result) which is more reliable as just !$result, because it's also covers empty objects.
As above noted, if the 'product_id' is not in the $_POST array, you could use $_REQUEST to also cover $_GET (but you shouldn't, if you are certain it's coming via $_POST).
I have this while loop, that basically loops through a lot of records in a database, and inserts the data in another:
$q = $con1->query($users1) or die(print_r($con2->errorInfo(),1));
while($row = $q->fetch(PDO::FETCH_ASSOC)){
$q = $con2->prepare($users2);
$q->execute(array($row['id'], $row['username'])) or die(print_r($con2-errorInfo(),1));
}
(The script has been shortened for easy reading - the correct one has a much longer array)
I would like to do this more graphical, and show a progress bar on how far it has went, instead of just seeing a page loading for a few minutes (there are ~20.000 rows in this one - I have tables with much more data)
I get that you could get the total number from the old database, and I could also easily put the current number into a variable like this:
$q = $con1->query($users1) or die(print_r($con2->errorInfo(),1));
$i = 0;
while($row = $q->fetch(PDO::FETCH_ASSOC)){
$q = $con2->prepare($users2);
$q->execute(array($row['id'], $row['username'])) or die(print_r($con2-errorInfo(),1));
$i++;
}
But now I need to actually fetch $i and display it - or something like it.
How is this "easily" done?
The code for the progress bar can either be in the same document as the while loop, or in another if easier.
You can do a "master" file that does an ajax to this first file to run a single query. You could get all the entry id's in this master file, and then pass it as a parameter to the second file that does a single query. Store these ids in a javascript array.
Create a function that does this, and when the first ajax is done, move to the second element of the id array, and do another ajax with a second parameter. That's how magento imports are done by the way :)
If you need further explanations, let me know, I tried my best to explain, but may have not been perfectly clear.
// you generate this javascript array using php.
// let's say you have all the ids that have to be processed in $Ids php array.
Ids = [<?php echo implode(',', $Ids); ?>];
function doAjax(i) {
$.ajax({ // using jquery for simplicity
'url': "ajax.php?id=" + Ids[i],
}).done(function(){
if ( i >= 0 ) {
// at the point you know you're at ((Ids.length-i)/(Ids.length) * 100) percent of the script
// so you can do something like this:
// $('.progressbar').css('width', ((Ids.length-i)/(Ids.length) * 100) + '%');
doAjax(i-1);
}
});
}
doAjax(Ids.length); // starting from the last entry
So, just to explain what this does. It starts by declaring a global javascript array that has all the ids that will need to be changed.
Then I declare a recursive ajax function, this way we can make sure that only one ajax runs at any single time (so the server doesn't blow up), and we can have a fairly accurate progress. This ajax function does the following:
Sends a request to ajax.php?id=xxx - where xxx is one of the ids in the javascript array.
In the file, we get the id ($_GET['id']), you take it from the old database, and insert it in the new one. This is only for one entry.
when the ajax is done, it goes to the done() function. Since we start the doAjax() function with the last element, we do the next iteration doAjax(i-1). Since we're going backwards in the array, we check if the key is positive. If it's not, the script will stop.
That's about it.
You can't. The php is first interpreted by the server and then send to the user as HTML-Code.
The only possibility would be creating a html-page and call the php-script with AJAX.