PHP and AJAX: cache RSS data - php

Consider the following AJAX call to load RSS news data on click event:
$(function() {
$(document).ready(function() {
$('.msg_head').eq(0).click(function(){
$('.msg_body').eq(0).load('printSideNews.php');
$('.loadMessage').eq(2).hide();
});
});
});
printSideNews.php looks like this:
include ('newsFeed.php');
function printNewsMenu($itemD){
for ($i = 0; $i < 4; $i++) {
if($itemD==null)
echo "An error has occured, please try again later";
$article_title = $itemD[$i]->title;
$article_link = $itemD[$i]->link;
echo "<a href='".$article_link."' title='".$article_title."' target='_blank'>". $article_title. " </a></br>". PHP_EOL;
}
printNewsMenu($itemD);
The included newsFeed.php file lloks like:
$urlD = "someurl";
$xmlD = simplexml_load_file($urlD);
$itemD = $xmlD->channel->item;
I need to cache the $itemD or the $xmlD object - not sure which one. This should be cached for 1 hour then taken again from the url. Any help with code caching this mess will be greatly appreciated.

take a look at this function:
<?php
function cacheObject($url,$name,$age = 86400)
{
// directory in which to store cached files
$cacheDir = "cache/";
// cache filename constructed from MD5 hash of URL
$filename = $cacheDir.$name;
// default to fetch the file
$cache = true;
// but if the file exists, don't fetch if it is recent enough
if (file_exists($filename))
{
$cache = (filemtime($filename) < (time()-$age));
}
// fetch the file if required
if ($cache)
{
$xmlD = simplexml_load_file($url);
$itemD = $xmlD->channel->item;
file_put_contents($filename,serialize($itemD));
// update timestamp to now
touch($filename);
}
// return the cache filename
return unserialize(file_get_contents($filename));
}
$urlD = "someurl";
$itemD = cacheObject($urlD,'cacheobject',3600);

Related

Need help caching json_decode(file_get_contents('api')) on wordpress website

I'm trying to retrieve data from coinmarketcap's api and store the data to cache file. If the cache file is older than 10 minutes, retrieve new data and store to cache file. I have been able to get everything to work, except for caching the data. The cache file is never created in the plugin directory. Any help would be appreciated. Here is the code :
function Tickers($data){
foreach($data as $item){
echo "$item->symbol";
echo "<br>";
echo '<span>$' . $item->price_usd . '</span>';
echo "<br>";
echo "<br>";
}
}
function getdata(){
$time = 600; //seconds
$cache_file = 'wp-content/plugins/cryptocurrency_tickers/cache.txt';
if(file_exists($cache_file)){
if(time() - filemtime($cache_file) > $time) {
// too old , re-fetch
$data = json_decode(file_get_contents('https://api.coinmarketcap.com/v1/ticker/?limit=20'));
file_put_contents(cache_file,json_encode($data));
}
else{
//data is current
}
}else {
// create cache
$data = json_decode(file_get_contents('https://api.coinmarketcap.com/v1/ticker/?limit=20'));
file_put_contents(cache_file, json_encode($data));
}
$data = json_decode(file_get_contents($cache_file));
Tickers($data);
}
Look at your code again, missing '$' in front of 'cache_file' on file_put_contents
file_put_contents(cache_file,json_encode($data));
should be
file_put_contents($cache_file,json_encode($data));
Also when you get the json data from the API first you decode, then encode, why you didn't save the data directly from the API, it's already json encoded.
Better version of your code:
function Tickers($data){
foreach($data as $item){
echo "$item->symbol";
echo "<br>";
echo '<span>$' . $item->price_usd . '</span>';
echo "<br>";
echo "<br>";
}
}
function getdata(){
$time = 600; //seconds
$cache_file = '/path/to/cache.txt';
if(file_exists($cache_file)){
if(time() - filemtime($cache_file) > $time) {
// too old , re-fetch
$data = file_get_contents('https://api.coinmarketcap.com/v1/ticker/?limit=20');
file_put_contents($cache_file, $data);
} else{
//data is current
}
} else {
// create cache
$data = file_get_contents('https://api.coinmarketcap.com/v1/ticker/?limit=20');
file_put_contents($cache_file, $data);
}
$data = json_decode(file_get_contents($cache_file));
Tickers($data);
}
getdata();
Also make sure the plugin directory is writable by your web server user.

Compare last GPS and current GPS data

I have a project where i need to send GPS coordinates via. socket in every 6 seconds. The coordinates are stored in a MYsql database. I run a query every 6 seconds and if the last position is different from the current position the application sends the data to the remote server. In the browser it works like a charm but in the terminal i can't use Sessions.
I tried apc_add but according to the PHP manual it is removed a long time ago.
What is the most common way to do a comparsion like that? Store the last coordinates into the database or a text file? Or is there a way to sotore it in run time?
**Here is my main code: **
<?php
require 'bootstrap.php';
use App\Libs\appServiceProvider;
use App\Libs\socketServiceProvider;
use Socket\Raw\Factory;
use App\Models\Koordinata;
$app = new appServiceProvider;
if (empty($_SESSION['lat']) || empty($_SESSION['lon'])) {
$_SESSION['lat'] = 0;
$_SESSION['lon'] = 0;
}
$lastLat = $_SESSION['lat'];
$lastLon = $_SESSION['lon'];
$currentLat = $app->getAllCoordinatesByFszgId($application['fszgId'])->last()->lat;
$currentLon = $app->getAllCoordinatesByFszgId($application['fszgId'])->last()->lon;
if ($lastLat != $currentLat && $lastLon != $currentLon) {
$factory = new Factory();
$socket = $factory->createClient('REMOTEADDRESSE');
echo "Kapcsolat létrehozva\n";
$socket->write("MESSAGE");
echo "Üzenet elküldve\n";
var_dump("Válasz: " . $socket->read(8192));
$socket->close();
} else {
echo "Idle";
$log->addDebug("GPS data NOT CHANGED! STATUS IDLE!");
}
$_SESSION['lat'] = $app->getAllCoordinatesByFszgId($application['fszgId'])->last()->lat;
$_SESSION['lon'] = $app->getAllCoordinatesByFszgId($application['fszgId'])->last()->lon;
?>
Okay, I did it with database and works fine. Here is the code:
<?php
require 'bootstrap.php';
use App\Libs\appServiceProvider;
use App\Libs\socketServiceProvider;
use Socket\Raw\Factory;
use App\Models\Koordinata;
use App\Models\TempKoordinata;
$app = new appServiceProvider;
$last = TempKoordinata::find(1);
if(!empty($last)) {
$lastLat = $last->lat;
$lastLon = $last->lon;
} else {
$temp = new TempKoordinata();
$temp->id = 1;
$temp->lat = 0;
$temp->lon = 0;
$temp->save();
$log->addDebug('No data to compare! Empty tempCoordinate table! Set values to ZERO!');
}
$currentLat = $app->getAllCoordinatesByFszgId($application['fszgId'])->last()->lat;
$currentLon = $app->getAllCoordinatesByFszgId($application['fszgId'])->last()->lon;
if ($lastLat != $currentLat && $lastLon != $currentLon) {
/*$factory = new Factory();
$socket = $factory->createClient('REMOTE');
echo "Kapcsolat létrehozva\n";
$socket->write("MESSAGE");
echo "Üzenet elküldve\n";
var_dump("Válasz: " . $socket->read(8192));
$socket->close();*/
echo "Sending\n";
} else {
echo "Idle\n";
$log->addDebug("GPS data NOT CHANGED! STATUS IDLE!");
}
TempKoordinata::destroy(1);
//Elmentjük a mostani GPS koordinátát
$count = TempKoordinata::all();
//Ha üres az adatbázis akkor elmentjük a koordinátákat
if ($count->count() == 0) {
$temp = new TempKoordinata();
$temp->id = 1;
$temp->lat = $currentLat;
$temp->lon = $currentLon;
$temp->save();
} else {
$log->addDebug("More than one item in the temp table!");
}
?>

PHP - Don't Count Users from index.php

I have a basic online visitors counter. I get it from here. It works verry well but I have a issue. I use it on online game and I have multiple servers. I use it for server online counter. I did add counter pages to the servers via iframe and it counts very well.
But the problem is, I want to display that numbers on index (index.php) page. But when I use :
<?php include("server1.php");?>
it counts index page users as well. I don't want this. How can I make it don't count IP's from index.php?
Here, my codes
Counter (server1.php)
<?php
$dbfile = "game/database/1.db"; // path to data file
$expire = 100; // average time in seconds to consider someone online before removing from the list
if(!file_exists($dbfile)) {
die("Error: Data file " . $dbfile . " NOT FOUND!");
}
if(!is_writable($dbfile)) {
die("Error: Data file " . $dbfile . " is NOT writable! Please CHMOD it to 666!");
}
function CountVisitors() {
global $dbfile, $expire;
$cur_ip = getIP();
$cur_time = time();
$dbary_new = array();
$dbary = unserialize(file_get_contents($dbfile));
if(is_array($dbary)) {
while(list($user_ip, $user_time) = each($dbary)) {
if(($user_ip != $cur_ip) && (($user_time + $expire) > $cur_time)) {
$dbary_new[$user_ip] = $user_time;
}
}
}
$dbary_new[$cur_ip] = $cur_time; // add record for current user
$fp = fopen($dbfile, "w");
fputs($fp, serialize($dbary_new));
fclose($fp);
$out = sprintf("%03d", count($dbary_new)); // format the result to display 3 digits with leading 0's
return $out;
}
function getIP() {
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
elseif(isset($_SERVER['REMOTE_ADDR'])) $ip = $_SERVER['REMOTE_ADDR'];
else $ip = "0";
return $ip;
}
$visitors_online = '0'+CountVisitors();
?>
<?=$visitors_online;?>
Iframe (I use it on server pages)
<iframe name="visitors" src="../1.php" width="1" hidden="true" height="1" frameborder="0" scrolling="no"></iframe>
php include (index.php)
Server 7 - Online Players:<?php include("7.php");?>
make a server2.php with this code
<?php
$dbfile = "game/database/1.db"; // path to data file
$expire = 100;
if(!file_exists($dbfile)) {
die("Error: Data file " . $dbfile . " NOT FOUND!");
}
if(!is_writable($dbfile)) {
die("Error: Data file " . $dbfile . " is NOT writable! Please CHMOD it to 666!");
}
function CountVisitors() {
global $dbfile, $expire;
$cur_time = time();
$dbary_new = array();
$dbary = unserialize(file_get_contents($dbfile));
if(is_array($dbary)) {
while(list($user_ip, $user_time) = each($dbary)) {
if(($user_time + $expire) > $cur_time) {
$dbary_new[$user_ip] = $user_time;
}
}
}
$out = sprintf("%03d", count($dbary_new)); // format the result to display 3 digits with leading 0's
return $out;
}
$visitors_online = '0'+CountVisitors();
?>
<?=$visitors_online;?>
and use it like server1.php

PHP - Icecast info being updated on page

I'm using a script from this site. This script works fine for me and it does what its need to do but I have one problem. When a track finishes on my Icecast server it doesn't get updates on the site. So if my song is 'Stole the show' than it says 'Stole the show' the page but when the song finished and e.g. 'Thinking out loud' starts the page still says 'Stole the show' on a refresh it will update. But how to make it so the page auto updates itself so the users doesn't have to refresh manually?
PHP
<?php
// include the class file
include( 'icecast.php' );
// instantiate class
$stream = new IceCast();
// set server and mount
$server = 'http://radio.finioxfm.com:8000';
$file = '/status.xsl';
// set the url
$stream->setUrl($server,$file);
// get status info
$radio = $stream->getStatus();
// assign array to variables
extract($radio);
// echo the status
echo $status.'<br/>';
// display more stats if ON AIR
if ($status=='ON AIR') :
echo $listeners.' listeners<br/>';
echo $title.'<br/>';
echo $genre.'<br/>';
for ($i=0; $i < 1; $i++) {
echo $now_playing['artist'].'<br/>';
echo $now_playing['track'].'<br/>';
}
endif;
?>
icecast.php script
<?php
class IceCast {
var $server = "http://radio.finioxfm.com:8000";
var $stats_file = "/status.xsl";
var $radio_info=array();
function __construct() {
// build array to store our Icecast stats
$this->radio_info['server'] = $this->server;
$this->radio_info['title'] = '';
$this->radio_info['description'] = '';
$this->radio_info['content_type'] = '';
$this->radio_info['mount_start'] = '';
$this->radio_info['bit_rate'] = '';
$this->radio_info['listeners'] = '';
$this->radio_info['most_listeners'] = '';
$this->radio_info['genre'] = '';
$this->radio_info['url'] = '';
$this->radio_info['now_playing'] = array();
$this->radio_info['now_playing']['artist'] = 'Unknown';
$this->radio_info['now_playing']['track'] = 'Unknown';
$this->radio_info['status'] = 'OFF AIR';
}
function setUrl($url,$file) {
$this->server=$url;
$this->stats_file=$file;
$this->radio_info['server'] = $this->server;
}
private function fetch() {
// create a new curl resource
$ch = curl_init();
// set the url
curl_setopt($ch,CURLOPT_URL,$this->server.$this->stats_file);
// return as a string
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
// $output = the status.xsl file
$output = curl_exec($ch);
// close curl resource to free up system resources
curl_close($ch);
return $output;
}
function getStatus() {
$output=$this->fetch();
// loop through $output and sort arrays
$temp_array = array();
$search_for = "<td\s[^>]*class=\"streamdata\">(.*)<\/td>";
$search_td = array('<td class="streamdata">','</td>');
if(preg_match_all("/$search_for/siU",$output,$matches)) {
foreach($matches[0] as $match) {
$to_push = str_replace($search_td,'',$match);
$to_push = trim($to_push);
array_push($temp_array,$to_push);
}
}
if(count($temp_array)) {
//sort our temp array into our ral array
$this->radio_info['title'] = $temp_array[0];
$this->radio_info['description'] = $temp_array[1];
$this->radio_info['content_type'] = $temp_array[2];
$this->radio_info['mount_start'] = $temp_array[3];
$this->radio_info['bit_rate'] = $temp_array[4];
$this->radio_info['listeners'] = $temp_array[5];
$this->radio_info['most_listeners'] = $temp_array[6];
$this->radio_info['genre'] = $temp_array[7];
$this->radio_info['url'] = $temp_array[8];
if(isset($temp_array[9])) {
$x = explode(" - ",$temp_array[9]);
$this->radio_info['now_playing']['artist'] = $x[0];
$this->radio_info['now_playing']['track'] = $x[1];
}
$this->radio_info['status'] = 'ON AIR';
}
return $this->radio_info;
}
}
?>
First of all, I have to point out that you shouldn't use this script. It works by parsing the Icecast Status page, which we highly discourage, as it may change. For example in Icecast 2.4 we re-made the complete web interface, so chances are that this script breaks.
You should actually parse the XML Icecast provides at http://icecast.tld:8000/admin/stats. It contains everything you need. If you can't access Icecast's Admin page for some reason, you can use the JSON at http://icecast.tld:8000/status-json.xsl, which is there since Icecast 2.4 exactly for the purpose you describe.
To get the site display new metadata information without refreshing, you need to use an AJAX call which either loads directly the status-json.xsl and extracts the metadata and updates it on the page, or if you use the admin XML you need to write a PHP script which returns json, that you can fetch via AJAX and update accordingly.
A lot of people in the past have spoken about setting up node.js (if you have a server doing your streaming).
Personally I have gone with a jquery solution; which just compares the last fetched data with the live data every 10 seconds. That way it loads in almost 'real time'.
You can find my solution here broken down here http://www.radiodj.ro/community/index.php?topic=7471.0

file copy progress session data is null

am trying to get progress of all the files being copied.
$qryStr = explode(",",$_POST['data']);
$timestamp=$_POST['timestamp'];
$size=sizeof($qryStr);
//echo $size;
$offset=100/$size;
$progress=0;
$_SESSION[$timestamp]=$progress;
session_start();
foreach($qryStr as $value) {
$src = $value;
$dest = "../home/tmp/";
$cmd = 'scp '.$src.' '.$dest.'';
sleep(1);
$progress+=$offset;
$_SESSION[$timestamp] = ceil($progress);
var_dump($_SESSION[$timestamp]);
$result = shell_exec($cmd);
}
code to get progress stored in session
session_start();
var_dump($_SESSION['timestamp']);
getProgress($_GET['timestamp']);
function getProgress($timestamp) {
if (isset($_SESSION[$timestamp])) {
echo json_encode(array("progress" => $_SESSION[$timestamp]));
} else {
echo json_encode(array("progress" => -1));
}
}
when i try to accesss the session data , am getting it as null. any problem in my script.
You have used $timestamp in the following line,
$_SESSION[$timestamp] = ceil($progress);
Instead, use
$_SESSION['timestamp'] = ceil($progress);
Only then it will be available in $_SESSION['timestamp'], else will be in $_SESSION['2013-10-28 14:33:00'], something like that which is non-generic.

Categories