Checking multiple fields from mysql with jquery AJAX in one call - php

I've got a page that seems to be in full working order, but I'm having major performance issues (think 30 second delay occasionally from these calls) from what I assume is throwing too many individual POST requests to the server.
Am I right in thinking that there's some way of doing it all in one call and that doing so would improve performance, and what's the easiest way of doing it? Perhaps my use of eval() is part of the problem - or maybe my webhost is just shit.
function startCheckAchs(){
//hide the loading alert
$(document).ajaxStop(function(){
$(this).unbind("ajaxStop");
popup('loadingAlert');
});
//load lifeTimeBaked
lifeTimeBaked = loadAch("lifetimebaked");
loadAch("ach_started", "#achStarted", "achstarted");
loadAch("ach_round1", "#achRound1", "achround1");
loadAch("ach_round2", "#achRound2", "achround2");
loadAch("ach_round3", "#achRound3", "achround3");
if( rewards == 1) {
loadAch("ach_baked100", "#achBaked100", "achbaked100");
loadAch("ach_baked500", "#achBaked500", "achbaked500");
loadAch("ach_baked1000", "#achBaked1000", "achbaked1000");
loadAch("ach_nobread", "#achNoBread", "achnobread");
loadAch("ach_nodough", "#achNoDough", "achnodough");
loadAch("ach_noflour", "#achNoFlour", "achnoflour");
loadAch("ach_allach", "#achAllAch", "achallach");
}
}
function loadAch(ach, achDiv, achVar){
$.ajax({
type: "POST",
url: "scripts/loadach.php",
data: {"achievement" : ach},
dataType: "text",
success: function(result){
if ( achDiv && achVar && result == 1){
$(achDiv).show();
eval(achVar + " = 1");
return result;
} else {
return result;
}
}
});
}
Loadach.php:
$achievement=trim($_POST['achievement']);
$user = $_SESSION['userid'];
$query = "SELECT $achievement FROM breadusers WHERE userid='$user'";
$link =#mysql_query($query);
if(!$link){
die('Could not query:' . mysql_error());
}
echo mysql_result($link, 0);
?>

You are currently loading achievements individually, while you should be doing something like:
<?php
$query = "SELECT ach_started, ach_round1 FROM breadusers WHERE userid='$user'";
$link = mysql_query($query);
$results = mysql_fetch_assoc($link);
echo json_encode($results);
?>
Then, in your javascript code, parse the JSON response (setting dataType: "json" should work), loop over the returned object (has keys such as ach_started, ach_round1, etc etc), and show/hide divs as needed.

Unfortunately you are going to have to redesign that.
SQL queries are slow.
Lots of requests make things slow.
See if you can group all of the data for a user in your database. That way you can make one select for all of the data you need.

You could use a multi-dimensional array and fill it with the data needed, send the array with ajax to the php code, and then you could loop through the array in the php code and echo back the desired results.
This way you would only be making 1 ajax call each time but still get the same results. might be faster this way but i have not tested this. =)

Most browsers have a limit on the number of concurrent server requests they can handle.
If you're using sessions, you'll also find that the server can only process a single request for each session at a time, because the session file is locked by each request, and subsequent requests must wait for it to be unlocked either when the first request finishes, or when a session_write_close() is issued by the executing request.

Related

Ajax/PHP long-polling results in 503 error

I'm playing around with AJAX long-polling and trying to read/update a simple counter (number) value in an MySQL cell by clicking on a button.
The PHP creates an infinite while loop and is checking if the value in the according cell has been modified (MySQL "current_timestamp", UNIX). If it has and the current_timestamp value is bigger then the timestamp the AJAX call was made, it's breaking the loop and sending the updated value and the updated current_timestamp to the client. The AJAX processes the data.
The Problem: It works but after a while I get a 503 error. I guess it's obviously the while loop or other open connections through multiple windows in other browsers (for testing).
PHP-File text.php:
// Connect to database
$con = mysql_connect('XX', 'XX', 'XX');
if (!$con)
{
die('Error' . mysql_error());
}
mysql_select_db('X', $con);
// Get data
$query = mysqli_query("SELECT counter_value, last_modified FROM content WHERE X = 'X' ORDER BY X DESC");
// Start infinite loop
set_time_limit(0);
while (true)
{
// The timestamp of the last ajax call = the last modified timestamp
$last_ajax_call = $_GET['timestamp'];
clearstatcache();
// Get the value of the counter and the last modified timestamp
while($row = mysql_fetch_array($query))
{
$counter_value = $row['counter_value'];
$last_modified= strtotime($row['last_modified']);
}
// If the time of the last modified timestamp is bigger/later than the last ajax call
if ($last_modified > $last_ajax_call)
{
$result = array(
'counter_value' => $counter_value,
'timestamp' => $last_modified
);
$json = json_encode($result);
echo $json;
break;
// If not, try again in 3 seconds
} else
{
sleep(3);
continue;
}
}
// Close database
mysql_close($con);
AJAX Part in js-File:
function getContent()
{
// get timestamp of last modified stored in attribute. The initial/first timestamp attribute is set beforehand.
var timestamp = $('#timestamp').attr('data-timestamp');
$.ajax(
{
type: 'GET',
url: 'test.php',
async: true,
cache: false,
data: {timestamp:timestamp},
success: function(data){
var obj = jQuery.parseJSON(data);
$("#counter").text(obj.counter_value);
$("#timestamp").attr("data-timestamp", obj.timestamp);
getContent();
}
}
);
}
getContent();
So the result is a 503 error which goes away after ca. 10 Minutes and it's working again.
(Any typos/formatting might be the result of cleaning up the code.)
I just started learning PHP and JS, so there might be a few newbie mistakes or weird lines in there, please be nice. Any advice on optimising the code is very appreciated!
It dies because PHP doesn't work the way you think it does.
You have intentionally put an infinite loop into your php in the assumption it will make your code keep looping around and rechecking the next GET request on each loop.
The reality is that the code is executed once for each request, and until execution of the code completes the server doesn't respond.
AJAX long polling requires no special handling in php, it's just an AJAX request in a loop. You might want to include a slight delay in your AJAX code otherwise your server will be hammered with requests.
To be honest this isn't what long polling is for, the idea of it is to update pages without any user interaction to display unread message notifications etc.
If you want to monitor user events like button clicks then bind your AJAX function to the clicking of the button.

Using Ajax to story response variable for php login

Ok so, some context. My college started doing some "learning on the job" type classes, and it's becoming a pain because it's like an internship without any sort of capacitation. Just my luck I was assigned a project I'm barely prepared for.
Right now I've been asked to join together an old Jamit Job Board with the login system of the place. Basically verify first if the user exist in the test database, then check if they exist in the local jobboard database. The problem is I don't have any ajax experience since it's not a topic we have touched in my classes. Sad, I know.
I was trying using cURL but was told by the supervisor it wouldn't work.
public function validar_request($Username,$Password) {
$Username = ($_REQUEST['username']);
$Password = md5(stripslashes($_REQUEST['password']));
function httpGet($url,p){
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
$output=curl_exec($ch);
curl_close($ch);
return $output;
}
$respuesta1 = httpGet("http://www01pruebasweb.fod.ac.cr/upe/templates/interfaces/ConexionFramework.php?procedimiento=nombreUsuarioExiste&username=".$Username);
The URL will return a 1 is the user exists in the testing database, 0 if not. I was thinking on doing a series of If else that if response = 1, then proceed to login, else donĀ“t since its like a 3 step verification process. First if the user exists, then if the password exists, and lastly if both tables in both databases match.
Response I get in the browser looks like this.
If the user usuario_01 exists then I should get a one. The idea me and a teammate had was to use curl to store the 1 into a variable in php and compare it but it's not working. Specially with the mess that is, for me, the other code for logging of Jamit. I mainly have experience with Java, not web development so as you can understand I'm very overwelmed.
I was trying to contact support from Jamit to see if they had any help, but they aren't active since 2013. Though not sure how much help they would be.
Not sure if necessary but part of the code for logging of Jamit is this
function validate_candidate_login($login_page='') {
global $login_output;
if ($login_output) { echo $login_output; return; } // this function was buffered
if ($login_page=='') {
$login_page = JB_BASE_HTTP_PATH.JB_CANDIDATE_FOLDER."index.php";
}
global $label;
$Username = ($_REQUEST['username']);
$Password = md5(stripslashes($_REQUEST['password']));
$sql = "Select * From users Where Username='".jb_escape_sql($Username)."'";
$result = JB_mysql_query($sql);
// init $row
if (mysql_num_rows($result)==0) {
$row = array();
} else {
$row = mysql_fetch_array($result, MYSQL_ASSOC);
}
JBPLUG_do_callback('val_can_set_pass', $Password); // Note for Plugin authors: Password is passed by refrence. Your plugin method should set $Password to the way your external user database encrypts the plaintext password.. eg $Password = md5($_REQUEST['password']); for phpBB
JBPLUG_do_callback('val_can_login', $row); // Note for Plugin authors: $row argument is passed by reference, which is the row of your users table. The row is populated if username/pass are valid, $row['Username'] and $row['Password'] are set for the code below and should come from your external database. You may also set $row['Validated'] too
if ((!$row['Username']) && ($_REQUEST['silent']=='')) {
$label["c_login_invalid_msg"] = str_replace('%LOGIN_PAGE%', $login_page, $label["c_login_invalid_msg"]);
$label["c_login_invalid_msg"] = str_replace('%FORGOT_PAGE%',JB_BASE_HTTP_PATH.JB_CANDIDATE_FOLDER."forgot.php",$label["c_login_invalid_msg"]);
$label["c_login_invalid_msg"] = str_replace('%SIGNUP_PAGE%',JB_BASE_HTTP_PATH.JB_CANDIDATE_FOLDER."signup.php",$label["c_login_invalid_msg"]);
echo '<p style="text-align:center; ">'.$label["c_login_invalid_msg"]."</p>";
} else {
if ($row['Validated']=="0") {
$label["c_login_notvalidated"] = str_replace('%BASE_HTTP_PATH%', JB_BASE_HTTP_PATH, $label["c_login_notvalidated"]);
echo '<p style="text-align:center; ">'.$label["c_login_notvalidated"].'</p>';
} else {
if (($Password === $row['Password']) || ((JB_ALLOW_ADMIN_LOGIN=='YES')&&(JB_ADMIN_PASSWORD===$_REQUEST['password']))) {
JBPLUG_do_callback('val_can_login_sync', $row); // Note for Plugin authors: Initialize $row with a Jamit user row. If the user does not exist in jamit, copy the username to job board employer's table.
JBPLUG_do_callback('val_can_login_set_session', $row); // Note for Plugin authors: set session variables for your external database (successful login)
JB_set_candidate_session($row); // set session for the candidate
$label['c_login_welcome'] = str_replace ("%FNAME%", JB_escape_html($_SESSION['JB_FirstName']), ($label['c_login_welcome']));
$label['c_login_welcome'] = str_replace ("%LNAME%", JB_escape_html($_SESSION['JB_LastName']), ($label['c_login_welcome']));
$label['c_login_welcome'] = str_replace ("%USERNAME%", JB_escape_html($_SESSION['JB_Username']), ($label['c_login_welcome']));
if (isset($_REQUEST['page'])) {
$label['c_login_welcome'] = preg_replace('/index\.php/i', htmlentities($_REQUEST['page']), $label['c_login_welcome']);
}
if ($_REQUEST['silent']=='') {
echo '<p style="text-align:center; ">'.$label["c_login_welcome"].'</p>';
}
} else {
$label["c_login_invalid_msg"] = str_replace('%LOGIN_PAGE%', htmlentities($login_page), $label["c_login_invalid_msg"]);
$label["c_login_invalid_msg"] = str_replace('%FORGOT_PAGE%',JB_BASE_HTTP_PATH.JB_CANDIDATE_FOLDER."forgot.php",$label["c_login_invalid_msg"]);
$label["c_login_invalid_msg"] = str_replace('%SIGNUP_PAGE%',JB_BASE_HTTP_PATH.JB_CANDIDATE_FOLDER."signup.php",$label["c_login_invalid_msg"]);
if (strpos($login_page, 'apply_iframe.php')!==false) {
$label["c_login_invalid_msg"] = str_replace('_parent', '_self', $label["c_login_invalid_msg"]);
}
echo '<div style="text-align:center;">'.$label["c_login_invalid_msg"].'</div>';
}
}
}
}
Ok cool - per the comments you're looking to get started with AJAX (Asynchronous Javascript And XML). I would highly recommend linking jQuery to your html page to get started - it will make AJAX calls MUCH easier.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
Awesome, now we have jQuery loaded, which allows you to make an ajax call with a simple function.
So now we need to get values from the browser to the server. How do we do that? There are 2 approaches I would recommend:
1 - Use JSON (Javascript Object Notation) to send data to the server with key/value pairs. PHP is great for working with JSON.
2 - Serialize a form using jQueries $(formElement).serialize() function. This turns forms into key/value pairs and you can then receive the data using PHPs $_POST['keyOfFormField']
So I'm going to assume you're going with the JSON approach, which is always preferable in my opinion.
If you're unfamiliar with javascript, JSON format looks like this:
var jsonExample = {'Im a key': 'and im its value'};
This is how you represent an object literal in javascript, and we can send these to the server and store them in an associative array in PHP.
So, on to the ajax call. I will leave it up to you to research ways of getting your data into JSON format. It should be really simple.
In jQuery, an AJAX call looks like this:
$.ajax({
url: 'urlOfServerFile.php',
async: true,
data: JSON.stringify({'Im a key': 'Im its value'}),
type: "POST",
datatype: 'json',
success: function (json) {
json = JSON.parse(json);
//The server sent you back some data, do something with it!
},
error: function () {
alert("Please check your internet connection and try again");
}
});
So what is this doing?
$.ajax() is a function. In jQuery, you basically get access to this really awesome object, which is the jQuery object (it's also represented by the $ sign). So, $.ajax() is the same thing as saying jQuery.ajax()
The $.ajax() function takes an object as an argument. Remember that the {} is how we encapsulate an object in javascript.
The documentation for this object can be found here: http://api.jquery.com/jquery.ajax/
Basically, we need to tell the $.ajax() function a few things:
url - where are we sending this request?
async - will this request be sent asynchronously?
data - what data are we sending to the server?
type - what type of HTTP request are we sending this data in (POST, PUT, GET, etc)
datatype - what type of data are we sending?
success - what do we do if the request is successful?
error - what do we do if the request fails?
Well, at this point we've successfully sent data from browser to server asynchronously. How do we handle this in PHP? Here's how:
$input = json_decode(file_get_contents('php://input'), true);
This variable, $input is now an associative array with all of the JSON key/value pairs that we sent over. So, now we can store some of those values in variables like this:
$randomVariable = $input['im a key'];
I hope this post will get you started with AJAX. Once you get the hang of it, it's a really intuitive technology that will make your applications WAY better.

Update php query limit whit js when load more

Hi I'm working on a reverse infinite scroll for a private message module.
The think is everything is working okay, my only problem is that I am not being able to update the limit of the query I am using.
The thing is a create the max and limit in php:
$max = mysql_num_rows($q_mensajes_contador_cargar);
$limit = $max-5;
Then when I use the infinite scroll I send the max and limit this way
$.ajax({
url: "formularios/cargar_mensajes.php?id=<? echo $id_receptor;?>&limite=<? echo $limit;?>",
success: function (html) {
if (html) {
$("#profile-feed-1").prepend(html);
$('div#loadmoreajaxloader').hide();
} else {
$('div#loadmoreajaxloader').html('<center>No more posts to show.</center>');
}
}
});
The thing is when I get this values in cargar_mensajes.php it just works once cause it is continually updating the same thing over and over, I want it to detect when it printed the next messages and update the query to show more or not show more depending in how many times it updates.
Sorry for my english...
Any advice, my js level is basic and I am sure that the way I am thinking this must not be the correct, just would like to know how can I achieve this.
Thank you!
You're setting the limit using PhP, so it never changes.
What you could do is :
var limit = <?php echo $limit; ?>
...
url: "formularios/cargar_mensajes.php?id=<? echo $id_receptor;?>&limite=" + limit,
success: function(html)
{
limit = limit + 5; // (Or -5, or whatever you need.)
Tell me if you need a more detailled code.

trying to put api data in database with php?

I'm pulling deals from Groupon's api, and I have no clue how to take the data and put it into a database with php, i know how to show it on in html, but not in the database, I need to pull it into the database so I have more control over the info, if anybody knows how to do this or knows a better way, i'm all eye's, lol, thanks
<script type='text/javascript'>
$(function () {
$.getJSON("https://api.groupon.com/v2/deals.json?callback=?",
{
client_id: "b252ad3634a4ab2985b79d230ccc4e49a3ea9d19",
show: "all",
division_id: "los-angeles"
})
.done(function (data) {
console.log(data);
// do whatever processing you need to do to the data
// right here, then drop it in the div
$.each(data.deals, function (i, v) {
$title = $("<h2/>", {
html: v.title,
class: "heading"
});
$img = $("<img/>", {
src: v.mediumImageUrl
});
$deal = $("<div/>", {
html: v.highlightsHtml + v.pitchHtml
});
$("#main").append($deal);
$deal.prepend($title, $img);
});
});
});
</script>
Theory
Well I'm just gonna start running through the process...
First, know which driver you are dealing with and research how PHP interacts with them. Look at this list and start reading...
http://www.php.net/manual/en/refs.database.php
Sending the data to a PHP script to handle the rest, depends on how you got the data. Here are some basic flows...
Pull it using jQuery, and use AJAX to send it as soon as you get it to the php script to save it. (Requires an additional HTTP request)
Pull it using PHP, save it to the DB, then format and output it on the same page. (Slows down initial page load time)
Pull it with jQuery, format it, and allow the user to press a button that will then ajax that entry to the PHP save script (More flexible, but greatly increases requests)
After you can get a connection to your database you just need to save it to a table using a SQL query (most likely using INSERT or UPDATE). With JSON data, I prefer to save it to a column that has the data type of TEXT. The only real risk here is that you have to be sure that you can validate the data. ESPECIALLY IF THE DATA IS BEING GIVEN TO PHP FROM A JAVASCRIPT /AJAX SOURCE!
Pulling the data from that point is just using a "SELECT" sql statement. PHP's database modules will pull this data and put it into a lovely array for you, making manipulation easy.
Examples
Now thats the theory, heres some actions. I'm going to be choosing the 1st flow idea. Now this one will just save it to the database. I'm not doing any fancy checking or really pulling. But this will show you the idea of how ajaxing and saving to php would work.
view-deals.html
<script type='text/javascript'>
$(function () {
$.getJSON("https://api.groupon.com/v2/deals.json?callback=?",
{
client_id: "b252ad3634a4ab2985b79d230ccc4e49a3ea9d19",
show: "all",
division_id: "los-angeles"
}).done(function (data) {
console.log(data);
// do whatever processing you need to do to the data
$.post('save-deals.php',{dealData: data}, function(finishData) {
//This is an optional function for when it has finished saving
});
// Your formatting comes next
....
});
</script>
Now that will send all the data that you got (intact) from groupon to a seperate php script using an AJAX Post call. I use post, well, because that's what it's for.
save-deals.php
ob_start(); //I like output-buffering because if we need to change headers mid script nothing dies
$DealData = isset( $_POST['dealData'] )?$_POST['dealData']:die("Malformed form data!");
if($DealData!='') {
$DB = new mysqli("example.com", "user", "password", "database");
if ($DB->connect_errno) {
echo "Failed to connect to MySQL: " . $DB->connect_error;
}
$DealData = $DB->real_escape_string($DealData); //Sanitize it for MySQL
if (!$DB->query("INSERT INTO deals(data) VALUES ($DealData)") {
echo "Insert failed: (" . $DB->errno . ") " . $DB->error;
} else {
//AT THIS POINT IT SHOULD HAVE BEEN INSERTED!
//You could return a success string, or whatever you want now.
}
} else {
http_response_code("400");
die("Bad Request, please check your entry and try again");
}
ob_end_flush(); //Close up the output-buffer
Some important things to note about that script is that the ob_* functions are completely optional. The way DealData is set is a VERY shorthand way of checking that the post data contains that value, and setting it properly; if not, then to give an error.
This next script is to show you how to pull the data from the database now, and manipulate it if you want. It will also return the data as JSON information so it can be used with a javascript $.getJSON() call. This is mostly a snippet for reference
manipulate-deals.php
//First connect to the database!
$DB = new mysqli("example.com", "user", "password", "database");
if ($DB->connect_errno) die("Failed to connect to MySQL: " . $DB->connect_error);
//Get ALL the entries!
if(!$results = $DB->query("SELECT * FROM data")) die("Failed to retrieve data! ".$DB->error);
//Decode the datas!
$returnResults = [];
while($entry = $results->fetch_assoc()) {
$JSON = json_decode($entry['data']);
//Manipulate however you wish!
$JSON->whatever->tags[1]->you->want = "whatever value";
//Add it to the results!
$returnResults[] = $JSON;
}
echo json_encode($returnResults);
That very last section is just for fun. It would export a json string containing an array of results. And each of that array's entries would be a valid object just as groupon had given you. Hope that helps!

Putting mySQL Database Information into a JavaScript Array

What I'm trying to do is create a slideshow by grabbing database information and putting it into a javascript array. I am currently using the jquery ajax function to call information from a separate php file. Here is my php code:
mysql_connect('x', 'x', 'x') or die('Not Connecting');
mysql_select_db('x') or die ('No Database Selected');
$i = 0;
$sql = mysql_query("SELECT comicname FROM comics ORDER BY upldate ASC");
while($row = mysql_fetch_array($sql, MYSQL_ASSOC)) {
echo "comics[" .$i. "]='comics/" .$row['comicname']. "';";
$i++;
}
What I want is to create the array in php from the mysql query and then be able to reference it with javascript in order to build a simple slideshow script. Please let me know if you have any questions or suggestions.
Ok have your .php echo json_encode('name of your php array');
Then on the javascript side your ajax should look something like this:
$.ajax({
data: "query string to send to your php file if you need it",
url: "youphpfile.php",
datatype: "json",
success: function(data, textStatus, xhr) {
data = JSON.parse(xhr.responseText);
for (i=0; i<data.length; i++) {
alert(data[i]); //this should tell you if your pulling the right information in
}
});
maybe replace data.length by 3 or something if you have alot of data...if your getting the right data use a yourJSArray.push(data[i]); I'm sure there's a more direct way actually...
You may want to fetch all rows into a large array and then encode it as a JSON:
$ret = array();
while($row = mysql_fetch_array($sql, MYSQL_ASSOC))
$ret[] = $row
echo json_encode($ret);
Then, on the client side, call something like this:
function mycallback(data)
{
console.log(data[0].comicname); // outputs the first returned comicname
}
$.ajax
(
{
url: 'myscript.php',
dataType: 'json',
success: mycallback
}
);
Upon successful request completion, mycallback will be called and passed an array of maps, each map representing a record from your resultset.
It's a little hard to tell from your question, but it sounds like:
You are making an AJAX call to your server in JS
Your server (using PHP) responds with the results
When the results come back jQuery invokes the callback you passed to it ...
And you're lost at this point? ie. the point of putting those AJAX results in to an array so that your slideshow can use them?
If so, the solution is very simple: inside your AJAX callback, put the results in to a global variable (eg. window.myResults = resultsFromAjax;) and then reference that variable when you want to start the slideshow.
However, since timing will probably be an issue, what might make more sense is to actually start your slideshow from within your callback instead. As an added bonus, that approach doesn't require a global variable.
If this isn't where you are stuck, please post more info.

Categories