I'm working on a jQuery AJAX call where I get a set of results from a search. I return html with an echo and I need to backup the results by inserting into the db. Will also have to check if they already exist before inserting.
I want the html to be returned as soon as possible. If I add insert code below the echo will the entire code have to finish running before the html is returned?
The most important thing is content returning back to the user right away.
This is all on mobile so every 100 milliseconds count.
$data = file_get_contents($url);
$result = json_decode($data, true);
foreach ( $result->results as $items ) {
$name = $items->name;
$description = $items->desc;
$id = $items->id;
$coverurl = $items->coverurl;
$returnhtml .= "<h3>".$name."</h3>";
$returnhtml .= "<h4>".$description."</h$>";
}
echo $returnhtml;
//how to backup to database
//check if already in db
//insert into db
To answer your question, yes. The entire script must complete before the HTML is outputted back to the client. You can use output buffering to capture the output, send it, and then continue on with other processing. The server will then try to output the remaining when the script finished but AJAX doesn't know how to handle the second part so it just ignores it.
Look into http://www.php.net/manual/en/ref.outcontrol.php
It'll be something like:
ob_start();
... generate html for client
ob_flush();// send output buffer to the client
... insert data into database
ob_end_clean();
After do the ob_flush as explained before, you can try MySQL INSERT DELAYED if you don't wait for the INSERT to complete.
http://dev.mysql.com/doc/refman/5.5/en/insert-delayed.html
Related
I'm currently using Chatfuel to open the index.php-file of my website which sends the user the html code into his browser. There he can register and set up his account.
An example URL might look like this:
https://my.domain.com?key_value='123456789'
Depending on if that user is a new or a existing one, I wanna present him with a different form. In order to check so, I do a simple query to the MySQL db and see if the passed on key_value is already in the db and safe true or false to a boolean. Stating the obvious: If hes not an existing user, the 'empty' form with no values should show up. If he is registered he should see the information he filled in from last time.
My idea:
At the top of my index.php I do the check whether he's an existing customer or not (Note: This is working already). Then I want to use outputbuffering to alter the html-code depending on the boolean, before it is sent to the client.
My problem:
I developed the blueprint of the website in plain html (see code below). And OB only catches it as output if its within a string. Since I use " as well as ' in the document the string gets interrupted every few lines. Is there a simple workaround to this? Because the OB function is unable to access anything within the <html>...</html> tags.
Or do i need to use redirecting after the check (in my index.php) and create a separate form + script for both edit customer data and add new customer data?
<?php
//Connection stuff
// Prepare statment: !TODO: string needs to be escaped properly first
$query_string = "SELECT * FROM tbl_customer WHERE unique_url = '$uniqueurl'";
$query_rslt = mysqli_query($conn, $query_string);
if($query_rslt == FALSE)
{
// Failure
echo "<br> Oops! Something went wrong with the querying of the db. " . $conn->connect_error;
//Handle error
}
else
{
if ($query_rslt->num_rows > 0)
{
// Set boolean
$existing_customer = TRUE;
// Create an array called row to store all tuples that match the query string
while($row = mysqli_fetch_assoc($query_rslt)) {
//...
}
}
}
// Custom post processing function
function ob_postprocess($buffer)
{
// do a fun quick change to our HTML before it is sent to the browser
$buffer = str_replace('Testing', 'Working', $buffer);
// Send $buffer to the browser
return $buffer;
}
// start output buffering at the top of our script with this simple command
// we've added "ob_postprocess" (our custom post processing function) as a parameter of ob_start
if (!ob_start('ob_postprocess'))
{
// Failure
echo "<br> Oops! Something went wrong with output buffering. Check that no HTML-Code is sent to client before calling this start function.";
// Handle error
}
else
{
// Success
// This is where the string should get accessed before sending to the client browser
echo "Testing OB.";
}
?>
<!--DOCTYPE html-->
<html lang="en">
<head>
<meta charset="utf-8">
//...
</body>
</html>
<?php
// end output buffering and send our HTML to the browser as a whole
ob_end_flush();
?>
Output: "Working OB."
EDIT: I added source code example. This code won't compile.
Since, i can't comment, so i'll put some of my question here.
I dont really get the point, but give me a try, are you mean escaping string? you can use backslashes \ to escape string.
Like this "select from ".$dbname." where id = \"".$id."\"".
You can easily using addslashes($var) before adding the variable to the sql. like this
$id = addslashes($_POST['id']);
$sql = "select form db where id = '$id'";
If you mean checking the existent of the user to select which form to show in the page, why dont you do this?
if(userCheck()) {
?>
// here write the html code if user passed
<?php
} else {
?>
// here write the html code if user not passed
<?php
}
You can put userCheck() as global function or whereever you place it, as long as you can use it when you want to check the user before showing the form.
tl;dr: The thing I was looking for was a combination of file_get_contents() and object buffering.
file_get_contents() returns a string of a plain html-file of your choice. I could post a ton of explanation here or simply link you to phppot.com. The article offers you a directly executable demo with source (Download here). In case you wanna try it with a html file of yours, simply change the file path.
So once the whole html was converted into a string, I used the postprocessing function of OB to alter the string (= basically my html) if it's an existing user that came to alter his data. Then all the html-code (in a string still at this point) is sent to the client using ob_end_flush(). I will put up the actual code asap :)
I am sorry to sound confusing but I will try to explain in the best way possible.
In the controller I have a function search
public function search(){
/*
I run my logics and get few URL from
where I need to fetch further data
the urls are saved in the URL array
$urls[0] = "http://url1.com/search1";
$urls[1] = "http://url2.com/search2";
I then set this in data variable and send it to view
so that It can be run in AJAX
I tired running get_file_contents but it executes
in series one after the other URL.
If there are 10 URL (5 secs per URL) the over all processing time
increases drastically
*/
$data["urls"] = $urls;
$resp = $this->load->view('ajaxer',$data,TRUE);
/* based on the $resp i need to run further business logic's */
}
Now the $resp is actually giving me only the HTML code. It is not executing the HTML and hence the ajax is not run.
Any thoughts on how to execute this will be really helpful.
Regards,
Amit
Your code is absolutelly ok. But your javascript is not getting any response data (only headers), because you are not returning any output.
If you want to "execute your HTML" you need to change the line with view to this:
$this->load->view('ajaxer',$data);
or this:
$resp = $this->load->view('ajaxer',$data,TRUE);
echo $resp;
You forgot to echo output in the controller. Apart from this you need few minor modification in your function.
public function search(){
/*
I run my logics and get few URL from
where I need to fetch further data
the urls are saved in the URL array
$urls[0] = "http://url1.com/search1";
$urls[1] = "http://url2.com/search2";
I then set this in data variable and send it to view
so that It can be run in AJAX
I tired running get_file_contents but it executes
in series one after the other URL.
If there are 10 URL (5 secs per URL) the over all processing time
increases drastically
*/
// You need to check either request came from Ajax request or not. If not it will echo passed string. It prevents to access this function besides Ajax request
if (!$this->input->is_ajax_request()) {
echo "Ajax Requests allowed.";
die;
}
$data["urls"] = $urls;
$resp = $this->load->view('ajaxer',$data,TRUE);
// Standard way to set response for output in json format.
// #param status will help to check all things goes correct or not. if not please pass false on the basis or your feature's requirement
$this->output->set_output(json_encode(array('status'=>true,'response'=>$resp)));
// Standard way to get output set above step.
$string = $this->output->get_output();
echo $string;
exit();
/* based on the $resp i need to run further business logic's */
}
Updated code is here. Hope you find your answer
I have the following code:
<?php
include "convert/xmlToArray.php";
$query_string = $_GET['query_string'];
if ($query_string == "") {
$query_string = "travel";
}
$completeurl = "http://my_site";
$xml = simplexml_load_file($completeurl);
$arrayData = xmlToArray($xml);
echo json_encode($arrayData);
?>
There is another page that fetches theses results with JavaScript and displays it to the user.
The page takes more than 10 seconds to fetch the results and display them.
Does anyone have any idea on how to make it load faster? Is there a client based solution?
Thanks
Save all your data to file php file. For example if you want get array you can simply include a file and use data. Its simply way to using php faster.
I've created autosave via Ajax for my content management system. Having problem. Problem is, when i'm testing on my local server, the php side updates big piece of data easily but when i'm testing it on my webhost, I see that, if the updated content is a big data, then php doesn't update the table row on the first attempt, updates only after second attempt. Any suggestion? How to deal with that problem?
PHP Side
<?php
session_start();
require '../../core/includes/common.php';
$err=array();
$name=filter($_POST['name'],$db);
$id=$db->escape_string($_POST['id']);
$title=filter($_POST['title'], $db);
$parentcheck=$db->escape_string($_POST['parentcheck']);
if(isset ($_POST['parent'])) $parent=$db->escape_string($_POST['parent']);
else $parent=$parentcheck;
$menu=$db->escape_string($_POST['menu']);
$content = html($_POST['content'], $db);
if (!isset($content)) die('error');
$result=$db->query("UPDATE pages AS p, menu AS m SET m.parent='$parent', m.name='$name', m.showinmenu='$menu', p.id='$id', p.title='$title', p.content='$content' WHERE m.id='$id' AND p.id=m.id") or die($db->error);
if ($result){
echo "{";
echo '"msg": "Success" ';
echo "}";
}
else{
echo "{";
echo
'"err": "Error"';
echo "}";
}
?>
Your code looks like you can have tons of potential errors, this example should only show what you can do to always return something back which might be in the format your AJAX request can deal with:
You're mixing two types of error handling: die'ing straight away and reporting your action result to AJAX. You should do the one way or the other, this one is reporting back always:
<?php
session_start();
require '../../core/includes/common.php';
...
if (!isset($content)) die('{"err": "No content"}'); // This will never happen BTW.
$result = $db->query("UPDATE pages AS p, menu AS m SET m.parent='$parent', m.name='$name', m.showinmenu='$menu', p.id='$id', p.title='$title', p.content='$content' WHERE m.id='$id' AND p.id=m.id");
if ($result)
{
echo '{"msg": "Success"'}';
}
else
{
echo '{"err": "Error"}';
}
?>
Can you do something like this, parse the html content for only the important content ie the div and not the entire page, Mysql text datatype supports 2GB, but its not safe to overload mysql.
Idea 1
Can you by any chance save the HTML content on an XML and refer the link along with the node in the Mysql Column so that AJAX picks up the xml and the node to display data on the fly.
Idea 2
Gzip the content and store in Mysql
i wanted to know somethings about the firebug,
when i try to load a page with firebug opend, it start the time lines.
what is :
waiting,
reciving,
DomContentLoaded,
Load,
mysql queries what affect from the list ? i see that more mysql queries i am adding, the reciving part is increasing.
let me paste a request that ihave used on my core , to generate a dynamic link or content.
function getContent($id = '') {
$id = mysql_real_escape_string ($id);
$sql = 'SELECT id,post_title,post_content FROM wp_posts WHERE post_category="67" ORDER BY post_date DESC LIMIT 1';
$res = mysql_query($sql) or die (mysql_error());
if (mysql_num_rows($res) !=0):
while ($row = mysql_fetch_assoc($res)) {
// this remove caption from wordpress, get 450 words to be used for exerpt, encode html,
$mycontent = $row['post_content'];
$mycontent = strip_tags($mycontent);
$mycontent = substr($mycontent,0,250);
$mycontent = preg_replace("/\[caption.*\[\/caption\]/", '', $mycontent);
$mycontent = htmlentities($mycontent);
//encode the words for html
$title = $row['post_title'];
$title = htmlentities($title);
echo '
<<h1>'.$title.' </h1>
<div class="cssclass"> '.$mycontent.' </div>
'; //echo
}
else:
echo 'This page dosnt exist.';
endif;
} // end
Is any thing wrong on this code or its normal, my db is about 75.000 lines.
Thank you for reading this post.
waiting: after sending a request to the server, this is the time spent waiting for data to start coming back
receiving: time spent receiving content
DomContentLoaded: time spent until the entirety of the DOM is availble (note, this is not all resources loaded, just the html portions, e.g. the </html> tag has been received/processed).
load: time until the entirety of the page, including images/scripts/css has been received/processed/loaded.
Don't worry about the receiving portion increasing. You're outputting more data, so it'll take more time to receive. That's perfectly normal.
Waiting is the time between when the browser sends the request and receiving any data at all from the server.
Receiving is the time actually getting data.
The reason Receiving is longer is because you're sending more data, so it's taking longer to download. You might expect Waiting time to go up slightly too, but the time to transfer across the network is more significant than the time spent processing the data on the server.