So I was making a comment system for my blogging cms project. All i want to achieve is to fetch comments every second from another php file (ex- comment.php) which is fetching data from MySql table, and show it in a div which is-
<div class="results" id="result"></div>
I was able to do it successfully, the text comments load well but image comments (comments having images in it) blinks every second.
probably due to AJAX refreshing the complete div every second.
I would really appreciate if someone can help me figure out how to stop this flickering.
my JavaScript code is-
<script>
function refresh_div() {
jQuery.ajax({
url:'comment.php',
type:'POST',
success:function(results) {
jQuery(".result").html(results);
var message=$('#result');
message.scrollTop(message[0].scrollHeight);
}
});
}
t = setInterval(refresh_div,1000);
</script>
here is the comment.php file, if needed-
<?php
session_start();
if(!isset($_SESSION['uid'])){
header('location:login.php');
}
include('config.php');
$sql = "SELECT * FROM messages ORDER BY id ASC LIMIT 0, 30 ";
$result = mysql_query($sql);
while($row = mysql_fetch_array($result)) {
$uname=$row['uname'];
$message=$row['message'];
echo "<span>".$uname."</span>";
echo ": ";
echo "<span style='font-family:myfont2;'>".$message."</span>";
echo "<br>";
}
?>
I read that image caching can solve the problem, but i expect an AJAX solution only if possible.
EDIT- You guys suggested me to keep old messages loaded and "Get only newest data in ajax". I believe I cannot do this on my own and expecting some code help.
Thanks
EXTRA NOTE- This is my first question here so my apologies if i didn't asked or explained it well or asked something i shouldn't have asked. Hope you good guys out there understand :)
You might consider using Etags.
The idea is simple - the comments.php adds an additional HTTP header (thus not breaking the existing functionality) which in some way allows the client (your Javascript) to ask the server "Only send me the updated content if it's changed since the version I already have").
The server-side needs to generated some sort of determinative value (it only changes if the data in the database changes - like a SHA hash) and provides that as an Etag value along with the response.
Your client (jQuery can do this for you) caches the Etag value, and on future requests includes the cached Etag in the request. If the server determines that the new response would result in an identical Etag (nothing changed) - it responds with a 304 Not Modified.
Wikipedia on Etags: https://en.wikipedia.org/wiki/HTTP_ETag
Etags in jQuery (see "ifModified" on the page): http://api.jquery.com/jquery.ajax/
For a quick demonstration of doing it in PHP: https://css-tricks.com/snippets/php/intelligent-php-cache-control/
Here they're using the modified time and MD5 hash of a file on disk. You'd need to modify these values to be appropriate for your SQL query result (you could base it off an auto-incrementing primary key from the comment table, for example, plus a DEFAULT CURRENT_TIMESTAMP()).
Related
As the title describe, the speed of jquery display data is 1 to 2 seconds slower than pure php. Demo at http://plekz.com/test-slow3.php . How to make jquery display data as fast as pure php?
Codes :
<div id="jqryd">
</div>
<script src="javascripts/jquery-1.5.js" type="text/javascript" language="javascript"></script>
<script type="text/javascript">
var jqryd = $('#jqryd');
jQuery.get("sale-show-month2.php", function(data) {
jqryd.html(data);
});
</script>
<?php
$sql = "SELECT payment_date, SUM(price) FROM sale WHERE seller_id=? && Year(payment_date)=? GROUP BY Month(payment_date) DESC"; //this is loged-in user.
$q = $conn->prepare($sql);
$result = $q->execute(array($user_id, $selected_year));
if(!$result){
die("Error Select user table query : ". implode(" : ", $q->errorInfo())); //if don't use implode, output of errorInfo() will be "Array".
}
while($r = $q->fetch(PDO::FETCH_ASSOC)){
$price_db2 = $r['SUM(price)'];
$payment_date_db = $r['payment_date'];
$payment_month_db = date("F", strtotime($payment_date_db));
$payment_month_db2 = date("m", strtotime($payment_date_db));
echo "This is pure php : " . $payment_month_db . " - " . $money_currency . $price_db2 ."<br>";
}
?>
Analyzing the traffic in your site example, I see that, other than result, in your sale-show-month2.php page you return even the jquery javascript. This slow down a lot the whole page: for some reason the network tracer see a querystring in the call like http://plekz.com/javascripts/jquery-1.5.js?_=1337691808625, that doesn't allow the cache to be used.
Simply avoid to return the link to jquery will improve performance.
Even after that you'll see jquery loaded data to come later, but this is due to the fact that the get method is called afeter the first page is loaded. You can see it very clearly with firebug or other tool (chrome and IE has their own).
With regards to the amount of data transfered between server and client I would always just transfer the minimum data required (probably using Plain text / XML or JSON depending on the data) and use the most efficient method to append it to the DOM
No matter how big the data is using the best (in your case fastest) method for appending to the DOM .. check out this jsperf for an indicator which method is fastest
And you will see that using the inbuild DOM creation methods are always faster, for example
var li = document.createElement('li');
li.innerHTML = i;
li.setAttribute('title', 'Element number ' + i);
li.setAttribute('class', 'list-item');
container.appendChild(li);
So in your case I would pass the data as JSON and then loop the nodes and append as required. If there is a lot of data returned then i would paginate the data - or show some initial data then add a "Show more" function that retrieved the next portion of data to be displayed.
With regards to the backend - I would ensure that my query was optimised and was using the correct indexes.
Your question doesn't really make sense. Check the network transfers with firebug or chrome - you'll see you spend about the same time waiting for data in both scenarios. However, after receiving the php'generated data the page takes ages to download jquery - and only then can it request the new data.
The only noteworthy thing is that it takes half a second to connect to your server with jquery - this lag will always be present if the connection is bad. With server-side generated data you'll get it once, with ajax you'll get it twice.
So in your scenario, you cannot speed up the fetch - unless you switch servers to something with proper throughput and proper response times.
While there are some ways to optimise the result, the answer to your question
How to make jquery display data as fast as pure php?
is: It is impossible.
Your Javascript will not be able to load anything into the DOM, until it is parsed and ready. This implies that the "pure PHP" data is already loaded, as it is delivered by the server as part of the main page.
It is only then, when the browser has to do another request to the server, taking another round-trip time, in order to get the AJAX version. So: no matter how good your server and your JS are, the AJAX version will never be as fast as the server-side version.
Note: This applies only for your setup with both version competing. Of course it could make sense to speed up the initial delivery of the HTML page by not using PHP and a database request, then loading some stuff later with AJAX.
I have set up the following:
Database class ($db)
Pagination class ($paginator)
I am attempting to write a basic system to let me administrate pages. I have a page "page_manager.php" in which I include both my database class (database.php) and my pagination class (paginate.php).
In my pagination class I have a function which echoes my SQL data. I've come up with a way to echo an HTML < select > element with the necessary IDs, which allows me to successfully echo the corresponding results (10 per page), based on the value of the < select > element. So, "1" will echo the first 10 results in the database, "2" will echo from 11-20, "3" will echo from 21-30, etc., etc..
I have added an onChange event to the < select > element which will copy its value (using "this.value") to a hidden form field. I then submit this form using document.getElementById().submit();
This will then add the $_GET variable to the URL, so the URL becomes ".../?pagenumber_form=X". However, when I try to grab this value back from the URL, the $_GET['pagenumber_form'] is empty.
Some code:
<span style='font-family: tahoma; font-size: 10pt;'>Page #</span>
<select id="page_number_selection"
onchange='javascript: document.getElementById("pagenumber_form").value = this.value;
document.getElementById("pagenumber").submit();'>
<?php
for($i = 1; $i <= $this->num_pages; $i++)
echo"<option id='" . $i . "'>" . $i . "</option>";
?>
</select>
<form name="pagenumber" id="pagenumber" action="" method="get">
<input type="text" name="pagenumber_form" id="pagenumber_form" />
</form>
So, I've tried using $_POST as well, but the same thing happens. I want to use $_GET, for a couple of reasons: it's easier to see what is happening with my values and the data I'm using doesn't need to be secure.
To recap: the $_GET variable is being added to the URL when I change the < select > element, and the corresponding value gets added to the URL as: ".../?pagenumber_form=X", but when I try to use the value in PHP, for example...
$page_number = $_GET['pagenumber_form'];
... I get a NULL value. :-(
Can anybody help me out please? Thank you.
EDIT:
I've just made a discovery. If I move my print_r($_GET) to my main index page, then the superglobals are returning as expected. My site structure is like this:
index.php
- JavaScript buttons use AJAX HTTP requests to include the "responseText" as the .innerHTML of my main < div >. The "responseText" is the contents of the page itself, in this case page_manager.php, which in turn includes pagination.php.
So in other words, my site is built from PHP includes, which doesn't seem to be compatible with HTTP superglobals.
Any idea how I can get around this problem? Thank you :-).
+------------------------------------------------------------------+
I can't answer my own posts, so:
The problem is not solved, but has been worked around.
I am certainly not very knowledgeable when it comes to PHP, but I am of the impression that using AJAX requests to include a PHP file in a document, which itself includes other PHP files, is not a good idea. The problem, I believe, was being caused because PHP is executed before the document is loaded in to the browser. Therefore, dynamically including a PHP file in a document will result in the improper working of said file due to the fact that PHP must be executed by the server before the page is rendered, and not after.
As such, I have stopped using AJAX for my site and am simply using good old PHP instead. I don't know enough to carry on using the AJAX requests, so that's an end to that problem.
Thanks to those who replied.
You need to re-pass the superglobals to the AJAX calls. So where you would make a request to pagination.php you need to make it to pagination.php?pagenumber_form=<?php echo $_GET['pagenumber_form']; ?>.
the corresponding value gets added to the URL as: ".../pagenumber_form=X
You might wanna try
.../?pagenumber_form=X
Included files can access superglobals just fine (which is what makes them super). What can't be done is to access variables from one request in another. It isn't that clear what your code is doing (since the question doesn't include a proper minimal test case–a complete, concise, representative sample), but it sounds like loading a single page involves multiple requests, and only the first of these is given the form data. Each AJAX request involves a separate HTTP request, and (because HTTP is supposed to be stateless) has different request data, so any request that isn't explicitly given the data won't have access to it. After a request is handled, all data the script has access to is discarded. This is why if you need data to exist across requests, you need some form of persistence, such as sessions (which you should be careful of, in order not to break the HTTP stateless model) or databases.
Some of the difficulty may lie in a confusion over exactly what happens server-side, what happens client-side, what happens between the two and in what order it all happens. Before you go further, read up on HTTP (a web search should reveal countless documents on the topic). You can use debuggers (e.g. Firebug, XDebug+a client, Wireshark, Live HTTP Headers) to peer at what's happening as it happens.
I am trying to use jQuery's fancy autocomplete function but I have a problem with speed of executing my script. Code snippet:
var data = <?php if(isset($names)) { echo json_encode(implode(" | ", array_unique($names))); } else { echo "null"; } ?>;
if (data != null) {
data = data.split(" | ");
$("#search_names").autocomplete(data);
}
My data comes from some MySQL table and is processed by PHP before jQuery pass it to input field. When I view source of such page there's enormous amount of text there (obviously) and the page itself loads between 5-10 seconds...
So I wonder is there a way to speed up my script somehow? I understand that there will be always so much text to process, whether in same file or in some other included file, but I just wonder am I stuck with 10sec loading page because of so much data or can I somehow make it more awesome? :)
Thanks for any help!
You should definitely use the remote autocomplete mechanism instead of filling all the data into the document every time.
The first argument can be an URL for remote data or an an array for local data.
For remote data: When the user starts typing, a request is send to the specified backend ("my_autocomplete_backend.php"), with a GET parameter named q that contains the current value of the input box and a parameter "limit" with the value specified for the max option.
if the lookups still take a lot of time, you will probably need to look into optimizing your PHP script instead of the jQuery part. Things like is the database using indexes, etc....
Looks like your using the following scritp: http://docs.jquery.com/Plugins/autocomplete
You should be using Ajax for this sort of thing, example:
$("#search_names").autocomplete('/ajax/autocomplete.php');
and then within your auto complete html you should do something like:
<?php
//Database
//Do Query: SELECT item FROM content WHERE {$escaped_q} ORDER BY item_hits DESC LIMIT {$escaped_limit}
//echo json_encode($results);
?>
Print the results as a JSON Object and it should work MUCH MUCH Faster.
I am working on my personal site, where I want to store my customers recent search result limited to that particular session.
I am using PHP platform and Javascripts.
Here is an example of what I am exactly looking at :
It stores your previously searched domain name for that particular session so that user can make decision by comparing those results.
Thanks.
EDIT- Well Thanks for all of your answers and suggestions.
But If you have noticed
above example
It looks like some kind of script loading a new content on the same page without refreshing it and keeping previous search content <div> as it is.
How to achieve this using javascripts or some sort of div layer ????
UPDATE START
This example uses page reload. If you want to do it without page reload, you can but you'll have to use AJAX to load new search results. But then, it's not a PHP question. I suggest looking at jquery library, as it makes it easy. Tutorials: http://docs.jquery.com/Tutorials and e.g. this one ( http://docs.jquery.com/Tutorials:Getting_Started_with_jQuery#Rate_me:_Using_Ajax ).
When loading data via AJAX, the page rendering result (in my example search.php) should return only HTML for results part, not whole HTML page. This is generally a first part of my tutorial (without session).
But I really think that AJAX in here is not really needed. Session is more reliable and allows access to your page from older / mobile browsers where not always JS works correctly.
UPDATE END
Ok then. Let's try the simple tutorial then. Sorry if too simple, but I don't know your exact level.
PHP has mechanism called sessions. In reality they are just bytes stored on server. Server knows which session is for each client by reading session cookie from client browser.
Not every page uses sessions (not every page needs it, and session uses server space, even if only temporarily), session is not enabled by default. To turn on session you use command
<?php session_start(); ?>
In most cases this is either run by PHP framework you use, or put near the top of your site. Session is definitely needed if you want to authenticate user somehow. Or in your case :)
To access session you can use superglobal $_SESSION variable (superglobal means that you can access it anywhere). It's an array, so session element will be e.g. $_SESSION['search'] etc.
As example, let's assume that your page looks like that
<html>
...
<form action="search.php" method="post">
Search: <input type="text" name="searchQuery" />
<input type="submit" value="Search" />
</form>
...
</html>
this very form will send user search to file named search.php. It can be the same file where the form resides - in simplest case when you put both your code and HTML in one file. Beginners often use this schema, although it's not advisable as result is a mess and hard to further change.
In search.php then, you'll use similar code:
<?php
if (!empty($_POST['searchQuery'])) //we have a new search
{
$result = do_search($_POST['searchQuery']);
}
?>
Then, somewhere below you'll display your search result ($result variable). do_search() function is your search mechanism, I guess you have it somewhere. You may have it not 'wrapped' in a function, then I advise to create it like that, it's much more useful.
function do_search($searchQuery)
{
...
return $result;
}
mind it, the above code doesn't use sessions yet. Let's add saving previous search results in session. The code may then look like that:
<?php
session_start(); //Starting session
//let's create session variable used to store results
if (!isset($_SESSION['searches']))
$_SESSION['searches'] = array();
if (!empty($_POST['searchQuery'])) //we have a new search
{
if (isset($_SESSION['searches'][$_POST['searchQuery']]) //User already searched on this value, delete previous result from sesion
{
unset($_SESSION['searches'][$_POST['searchQuery']]);
}
$result = do_search($_POST['searchQuery']);
//Let's add new search on the begining of session array to make iterations easier.
$result = array($_POST['searchQuery'] => $result); //convert result to same format as session table
$_SESSION['searches'] = array_merge($result, $_SESSION['searches']);
}
?>
In display you'll now not iterate on $result variable as before, but instead you will do something like
foreach ($_SESSION['searches'] as $query => $result)
{
...//display of single result
}
I haven't tested following code and it's not a full program. Parts to display result and to do actual search are not described but I guess you have them already prepared. Also, this is only one possible approach of countless possibilities. But I hope this helps :)
Possible modification - now I always perform search, even if user already searched on this term. You may want to receive the result from cache without second search. Then the code will look like
if (isset($_SESSION['searches'][$_POST['searchQuery']]) //User already searched on this value
{
$result = $_SESSION['searches'][$_POST['searchQuery']];
unset($_SESSION['searches'][$_POST['searchQuery']]);
}
else
{
$result = do_search($_POST['searchQuery']);
}
For more in-depth information about sessions and some other constructs used in my example I suggest PHP manual
http://pl.php.net/manual/en/book.session.php
and various tutorials over the network. Or you can add a comment here :)
Put this code near the beginning of your script(s):
if (!isset($_SESSION['previous_searches']) || !is_array($_SESSION['previous_searches'])) {
$_SESSION['previous_searches'] = array();
}
[edit]
This code snippet checks if if there is already an array with prevous searches and if not it will be created.
[/edit]
Then when the user hits the search page put this code in the receiving script of the search:
$_SESSION['previous_searches'][] = $_GET['what_ever_your_search_value_might_be'];
[edit]
This code snippet adds the current search value to the and of the array with previous search values
[/edit]
Now you have all previous search values in $_SESSION['previous_searches']
If your website is a web application where you never reload the page nor change the page, you can keep it JavaScript in a global store (declare at top level something like var StoredSearch = []; and use it). If not, then use $_SESSION to store this and AJAX to save/load searches from JavaScript to PHP.
Im pulling the binary data out of my mySql database and want to display it as a image.
I do not want to make a separate page for it to display the image (this would involve a extra call to the databae among other things)
I simply want to be able to do
Pretty much but the $Image variable is in its longblob format and I need to convert it.
THanks in advance.
I know this is not a specific answer to your question, but consider that by removing that database call, you are dramatically increasing your server load, increasing the size of each page and slowing down the responsiveness of your site.
Consider any page stackoverflow. Most of it is dynamic, so the page cannot be cached. but the users' thumbnail is static and can be cached.
If you send the thumbnail as a data URI, you are doing the DB lookup and data transfer for every thumbnail on every page.
If you send it as a linked image, you incur a single DB lookup for when the image is first loaded, and from then on it will be cached (if you send the correct HTTP headers with it), making your server load lighter, and your site run faster!
I do not want to make a separate page for it to display the image
You can base64 encode your image data and include it directly into the markup as a data URI. In most cases, that's not a good idea though:
It's not supported by IE < 8
It (obviously) sizes up the HTML page massively.
It slows down rendering because the browser has to load the resource first before it can finish HTML rendering
Better build a separate script, and make that one extra call.
You could probably do this using Base64-encoded Data URIs.
I'm not sure if it's possible to do straight into a img-tag, but you can do it by setting a background-image for a div.
Basically you change the regular
.smurfette {
background: url(smurfette.png);
}
to
.smurfette {
background: url(data:image/png;base64,iVBORw0KGgo [...] P6VAAAAAElFTkSuQmCC);
}
Data URIs are supported in:
* Firefox 2+
* Safari – all versions
* Google Chrome – all versions
* Opera 7.2+
* Internet Explorer 8+
Info borrowed from Robert Nyman: http://robertnyman.com/2010/01/15/how-to-reduce-the-number-of-http-requests/
$_GET the result into a separate variable i.e. $myvar = $_GET['Id']; before you process the $imageResult line e.g.:
$myid = $_GET['Id'];
$ImageResult = "select player.Image from player where Id = '$myid'";
thanks for the answers, ive decided to go with a separate GetImage.php page but now cant seem to do the simplest of tasks
$ImageResult = "select player.Image from player where Id = " . $_GET['Id'];
$result = mysql_query($ImageResult) or die ("data recovery failed -3");
header("Content-type: image/jpeg");
echo mysql_result($result, 0);
But this returns just a broken link and cannot work out what I have missed out