biscuit_ biscuit_ - 6 months ago 41
Javascript Question

Cache data server side for ajax request

I'm using TwitterAPIExchange and Instagram-PHP-API to request data from both APIs on my server, concatenate them into an array and build this into JSON which I can consume on the client with a simple GET request in jQuery.

This is all working fine, however it is quite slow. When I make a request to static JSON data as a test, it is far quicker. It seems the php script on my server to get this data is running each time (so starting with an empty array, using the wrappers the libraries provide to make requests etc.). What I would like to do is to cache/store this data, and only make another request once or twice a day.

My PHP knowledge is not the best so I'm sure there is a relatively simple way of doing this.

Here is the php script on my server:

<?php

header('Content-type:application/json;charset=utf-8');

require_once('TwitterAPIExchange.php');
require_once('Instagram.php');

unset($allFeeds);
$allFeeds = array();

$settings = array(
'oauth_access_token' => "XXXX' => "XXXX",
'consumer_key' => "XXXX",
'consumer_secret' => "XXXX"
);

$url = 'https://api.twitter.com/1.1/statuses/user_timeline.json';
$getfield = '?screen_name=XXX';
$requestMethod = 'GET';

$twitter = new TwitterAPIExchange($settings);

$twitter_response = $twitter->setGetfield($getfield)->buildOauth($url,$requestMethod)->performRequest();


$jsonTweets = json_decode($twitter_response);

foreach ($jsonTweets as $tweet) {

$tweetObj = new stdClass();
$tweetObj->type = 'Twitter';
$tweetObj->created_at = strtotime($tweet->created_at);
$tweetObj->text = $tweet->text;
$allFeeds[] = $tweetObj;
}

use MetzWeb\Instagram\Instagram;

$instagram = new Instagram(array(
'apiKey' => 'XXXX',
'apiSecret' => 'XXXX',
'apiCallback' => 'XXXX'
));

$token = 'XXX';
$code = $token;
$instagram->setAccessToken($code);

$id_one = 'XXX';
$id_two = 'XXX';

$insta_response_one = $instagram->getUserMedia($id_one, 20);
$insta_response_two = $instagram->getUserMedia($id_two, 10);

foreach ($insta_response_one->data as $insta_one) {
$instaObjOne = new stdClass();
$instaObjOne->type = 'Instagram One';
$instaObjOne->created_at = (int)$insta_one->created_time;

if (isset($insta_one->caption->text)) {
$instaObjOne->text = $insta_one->caption->text;
}

$instaObjOne->img = $insta_one->images->standard_resolution->url;
$allFeeds[] = $instaObjOne;

}

foreach ($insta_response_two->data as $insta_two) {
$instaObjTwo = new stdClass();
$instaObjTwo->type = 'Instagram Two';
$instaObjTwo->created_at = (int)$insta_two->created_time;
if (isset($insta_two->caption->text)) {
$instaObjTwo->text = $insta_two->caption->text;
}
$instaObjTwo->img = $insta_two->images->standard_resolution->url;
$allFeeds[] = $instaObjTwo;
}

function dateSort($a, $b) {
return $b->created_at - $a->created_at;
}

usort($allFeeds, "dateSort");

$data = json_encode($allFeeds);

// cache $data here?

echo $data;

?>


I bringing it into my frontend like so:

$.ajax({
type: 'GET',
url: 'path/to/script.php'
dataType: 'json',
}).done(function(data) {
// do stuff with data here
});
}


Hope that makes sense, thanks

Answer

Just wanted to flesh out my comment into an answer. This is the simplest way to adding caching to your code.

It's using file_put_contents('cache.txt',$data) to cache the request data and then at the top of the file it checks the current time and compares with the last time the file was modified. If it was modified less than 24 hours ago, it just outputs the content of the cache file and stops the script.

<?php

header('Content-type:application/json;charset=utf-8');

// Check if file was modified less than 24 hours ago
if ((time() - filemtime('cache.txt')) < 24 * 60 * 60) { 

    // Output contents of cache file and stop script
    echo file_get_contents('cache.txt');
    exit(); 
}

require_once('TwitterAPIExchange.php');
require_once('Instagram.php');

unset($allFeeds);
$allFeeds = array();

$settings = array(
'oauth_access_token' => "XXXX" => "XXXX",
'consumer_key' => "XXXX",
'consumer_secret' => "XXXX"
);

$url = 'https://api.twitter.com/1.1/statuses/user_timeline.json';
$getfield = '?screen_name=XXX';
$requestMethod = 'GET';

$twitter = new TwitterAPIExchange($settings);

$twitter_response = $twitter->setGetfield($getfield)->buildOauth($url,$requestMethod)->performRequest();


$jsonTweets = json_decode($twitter_response);

foreach ($jsonTweets as $tweet) {

 $tweetObj = new stdClass();
 $tweetObj->type = 'Twitter';
 $tweetObj->created_at = strtotime($tweet->created_at);
 $tweetObj->text = $tweet->text;
 $allFeeds[] = $tweetObj;
}

use MetzWeb\Instagram\Instagram;

$instagram = new Instagram(array(
 'apiKey'      => 'XXXX',
 'apiSecret'   => 'XXXX',
 'apiCallback' => 'XXXX'
));

$token = 'XXX';
$code = $token;
$instagram->setAccessToken($code);

$id_one = 'XXX';
$id_two = 'XXX';

$insta_response_one = $instagram->getUserMedia($id_one, 20);
$insta_response_two = $instagram->getUserMedia($id_two, 10);

foreach ($insta_response_one->data as $insta_one) {
 $instaObjOne = new stdClass();
 $instaObjOne->type = 'Instagram One';
 $instaObjOne->created_at = (int)$insta_one->created_time;

  if (isset($insta_one->caption->text)) {
   $instaObjOne->text = $insta_one->caption->text;
  }

$instaObjOne->img = $insta_one->images->standard_resolution->url;
$allFeeds[] = $instaObjOne;

}

foreach ($insta_response_two->data as $insta_two) {
 $instaObjTwo = new stdClass();
 $instaObjTwo->type = 'Instagram Two';
 $instaObjTwo->created_at = (int)$insta_two->created_time;
 if (isset($insta_two->caption->text)) {
   $instaObjTwo->text = $insta_two->caption->text;
 }
$instaObjTwo->img = $insta_two->images->standard_resolution->url;
 $allFeeds[] = $instaObjTwo;
}

function dateSort($a, $b) {
 return $b->created_at - $a->created_at;
}

usort($allFeeds, "dateSort");

$data = json_encode($allFeeds);

// Cache $data here
file_put_contents('cache.txt', $data);

echo $data;

?>
Comments