How to periodically push data to the user interface in php - php

i need to implement a simple project using PHP and MySql in which i need to push data to the user's UI when some one else is updating the database, and i need to periodically do this too, so when some one else accessing the same table and modify it, another person who uses the UI can see the updates, sorry if i'm being silly but up to now i'm only aware of saving data to a database and retrieving and showing it to the user(simplest form of data base connection). how can i achieve this in php, please some one help me on this matter, if the answer explains the things in detail it is good, because i'm very novice to this.thanks in advance.
rangana.

If the web page has no data to return, then get the page to wait for a period while polling the database. You must use the sleep statement to avoid maxing out your server.
Warning: Some servers wont let the user open another page while one is in progress, which may cause you problems in some situations. So either dont hold the page open for too long, or maybe try to get the ajax page to use a different session.
// do this when you have put new data in to database
setappdata("lastupdate",microtime(true));
// use this loop to poll for new data
$loop = 0;
$lastupdate=$_SESSION["lastupdate"];
while ($lastupdate==$last=getappdata("lastupdate") and $loop<10) {
$loop++;
usleep(500000); //0.5sec
}
// use a table called appdata to store application data
function getappdata($var) {
$query = "SELECT data FROM appdata WHERE var='$var'";
$res1=mysql_query($query);
if (mysql_numrows($res1)<1) return false;
return mysql_result($res1,0,"data");
}
function setappdata($var,$data) {
$query = "SELECT data FROM appdata WHERE var='$var'";
$res1=mysql_query($query);
if (mysql_numrows($res1)>0) $query = "UPDATE appdata SET data='$data' WHERE var='$var'";
else $query = "INSERT INTO appdata SET var='$var',data='$data'";
return mysql_query($query);
}

These topics may get you started:
http://en.wikipedia.org/wiki/Push_technology
http://en.wikipedia.org/wiki/Reverse_Ajax

Related

PHP DB caching, without including files

I've been searching for a suitable PHP caching method for MSSQL results.
Most of the examples I can find suggest storing the results in an array, which would then get included to page. This seems great unless a request for the content was made at the same time as it being updated/rebuilt.
I was hoping to find something similar to ASP's application level variables, but far as I'm aware, PHP doesn't offer this functionality?
The problem I'm facing is I need to perform 6 queries on page to populate dropdown boxes. This happens on the vast majority of pages. It's also not an option to combine the queries. The cached data will also need to be rebuilt sporadically, when the system changes. This could be once a day, once a week or a month. Any advice will be greatly received, thanks!
You can use Redis server and phpredis PHP extension to cache results fetched from database:
$redis = new Redis();
$redis->connect('/tmp/redis.sock');
$sql = "SELECT something FROM sometable WHERE condition";
$sql_hash = md5($sql);
$redis_key = "dbcache:${sql_hash}";
$ttl = 3600; // values expire in 1 hour
if ($result = $redis->get($redis_key)) {
$result = json_decode($result, true);
} else {
$result = Db::fetchArray($sql);
$redis->setex($redis_key, $ttl, json_encode($result));
}
(Error checks skipped for clarity)

Save temporary data with CakePhp

I am looking for a solution in CakePhp, to store and read temporary datas :
I read some XML from others websites in order to display some news in my website, but on each page load, it does a call to the other xml websites.
Is there a way (memcached like) to save temp. data in CakePhp in order to store data for 1 hour and read temp. data to display them in my webpages ; then 1 hour after update them (with cron) ?
Thanks.
CakePHP Caching seems what you'd want.
WHICH cache you use (Redis, Memcache...etc) would be up to you though. Set your cache to last an hour, and you're all set. (read more about cache on the link above).
If you're on CakePHP 2.5+, you can use the remember method described here.
public function newest() {
$model = $this;
return Cache::remember('newest_posts', function() use ($model){
// get your data from whatever source here, and return it
return $model->getMyData();
}, 'long');
}
Basically, this just checks to see if the cache key exists, and if not, runs some code in order to populate it again.
If you're below 2.5, you can do the same basic thing, but without the remember:
public function newest() {
$result = Cache::read('newest_posts', 'long');
if (!$result) {
// get your data from whatever source here, and write it
Cache::write('newest_posts', $this->getMyData(), 'long');
}
return $result;
}
If you don't have a cache engine installed or are aren't wanting to mess w/ your own server, there are companies that you can use for cache, and you can just set your cache settings to connect to them. ObjectRocket (Redis) is the one I know offhand, but I'm sure there are plenty.
One of many awesome things about CakePHP, is that in this case, your code doesn't change regardless of Cache type/location/configuration you choose.

Prevent PHP from sending multiple emails when running parallel instances

This is more of a logic question than language question, though the approach might vary depending on the language. In this instance I'm using Actionscript and PHP.
I have a flash graphic that is getting data stored in a mysql database served from a PHP script. This part is working fine. It cycles through database entries every time it is fired.
The graphic is not on a website, but is being used at 5 locations, set to load and run at regular intervals (all 5 locations fire at the same time, or at least within <500ms of each-other). This is real-time info, so time is of the essence, currently the script loads and parses at all 5 locations between 30ms-300ms (depending on the distance from the server)
I was originally having a pagination problem, where each of the 5 locations would pull a different database entry since i was moving to the next entry every time the script runs. I solved this by setting the script to only move to the next entry after a certain amount of time passed, solving the problem.
However, I also need the script to send an email every time it displays a new entry, I only want it to send one email. I've attempted to solve this by adding a "has been emailed" boolean to the database. But, since all the scripts run at the same time, this rarely works (it does sometimes). Most of the time I get 5 emails sent. The timeliness of sending this email doesn't have to be as fast as the graphic gets info from the script, 5-10 second delay is fine.
I've been trying to come up with a solution for this. Currently I'm thinking of spawning a python script through PHP, that has a random delay (between 2 and 5 seconds) hopefully alleviating the problem. However, I'm not quite sure how to run exec() command from php without the script waiting for the command to finish. Or, is there a better way to accomplish this?
UPDATE: here is my current logic (relevant code only):
//get the top "unread" information from the database
$query="SELECT * FROM database WHERE Read = '0' ORDER BY Entry ASC LIMIT 1";
//DATA
$emailed = $row["emailed"];
$Entry = $row["databaseEntryID"];
if($emailed == 0)
{
**CODE TO SEND EMAIL**
$EmailSent="UPDATE database SET emailed = '1' WHERE databaseEntryID = '$Entry'";
$mysqli->query($EmailSent);
}
Thanks!
You need to use some kind of locking. E.g. database locking
function send_email_sync($message)
{
sql_query("UPDATE email_table SET email_sent=1 WHERE email_sent=0");
$result = FALSE;
if(number_of_affacted_rows() == 1) {
send_email_now($message);
$result = TRUE;
}
return $result;
}
The functions sql_query and number_of_affected_rows need to be adapted to your particular database.
Old answer:
Use file-based locking: (only works if the script only runs on a single server)
function send_email_sync($message)
{
$fd = fopen(__FILE__, "r");
if(!$fd) {
die("something bad happened in ".__FILE__.":".__LINE__);
}
$result = FALSE;
if(flock($fd, LOCK_EX | LOCK_NB)) {
if(!email_has_already_been_sent()) {
actually_send_email($message);
mark_email_as_sent();
$result = TRUE; //email has been sent
}
flock($fd, LOCK_UN);
}
fclose($fd);
return $result;
}
You will need to lock the row in your database by using a transaction.
psuedo code:
Start transaction
select row .. for update
update row
commit
if (mysqli_affected_rows ( $connection )) >1
send_email();

Retrieve constantly from database

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_*

sync two tables from two different PostgreSQL databases

I have two tables from two different databases and I want a php function to syncronize the data, so that the table number 2 can always verify the content on the table 1 and update it's information.
Anyone has one example on how to do that? Thanks in advance.
D.S.'s answer will get the job done.
You could also look into setting up an after insert/update trigger and using dblink. That way, they'll be kept in sync without you needing to worry about it in PHP.
As a side note, be very wary of what might happen on DB errors in either case. You can end up losing sync with either solution when DB errors occur, because the transactions will be autonomous.
this example will connect to both the databases, and for each of the first db's authors will update the destination db's author with the same id.
Of course you have to set up any necessary check, search and other details before perform and update (or an insert or replace if you prefer), but it fully depends on what you're going to do :)
<?php
if (false !== ($con1 = pg_connect("your source connection string"))) {
if (false !== ($con2 = pg_connect("your dest connection string"))) {
if (false !== ($result = pg_query($con1, "SELECT id, author, email FROM authors"))) {
while (false !== ($row = pg_fetch_assoc($result))) {
pg_query($con2, "UPDATE authors SET email=".pg_escape_string($con2, $row['email']).
'WHERE id='.pg_escape_string($con2, $row['id']));
}
pg_free_result($result);
}
pg_close($con2);
}
pg_close($con1);
}
?>
I hope it was useful. Please feel free to ask any question about it. Enjoy! :)
Create trigger on Insert, Update, Delete. When trigger procedure called store all the changes done in operation(Insert, update or delete) into database table(let's call this sync_table). Run some script which will copy data from sync_table to another database table. sync_table will store what data modified, inserted and deleted.

Categories