1

I'm displaying Highcharts on my site which visualizes the data of an external API. Instead of calling this API with every pageview, I'd like to store the retrieved data locally in a cache file. The next user who visits the page then should get the Highcharts data from that local cache file, instead from the API URL (in order to reduce API calls and Highcharts load time). The cache file should be considered up-to-date for 60 minutes.

I've found an answer here 5-minute file cache in PHP, but it's not working for me.

I basically copied the code into my own php file:

....
//to be sure about the correct file path, 
//I used here the absolute URL of my site: "https://www.example.com/path/to/my/cache.json"
$cache_file = "path/to/my/cache.json";

$api_url = "http://www.someapi.com/api";

if (file_exists($cache_file) && (filemtime($cache_file) > (time() - 60 * 60 ))) {
// Cache file is less than 60 minutes old. 
//Don't bother refreshing, just use the file as-is.
    $json = file_get_contents($cache_file);

} else {
//Our cache is out-of-date, so load the data from our remote server, 
//and also save it over our cache for next time.
    $json = file_get_contents($api_url);
    file_put_contents($cache_file, $json);
}

//decode JSON to array
$data = json_decode($json,true);
....

WhenI load my site, the the Highcharts are displaying the results but apparently only by the API URL. My cache.json file remains empty. I gave it chmod 777 and so I did for the parent directory data and dataCache.

In order to test the code, I tried to debug by out-commenting the line

//$json = file_get_contents($api_url);

What happens then is that the Highcharts don't display any data at all. So I learned that the IF loop is somewhat working - but not the way it should.

I then copied the JSON data from the API response, and saved it into my cache.json file. Now I out-commented the line

//$json = file_get_contents($api_url);

I was hoping that since I have a freshly created cache.json file, the first IF condition would be met and therefore the Highcharts would retrieve the data from my cache file. However, that didn't happen. The Highcharts don't display any data again.

Can you please help me understand why the code is not working (although I copied it basically from here 5-minute file cache in PHP)?

P.S.: I am not sure if this maybe just a "duplicate" question. But since the answer in the original question doesn't work for me, I was not sure how/where to ask.

bauhausweb
  • 135
  • 1
  • 13

1 Answers1

0

Your problem may be the extrnal URL.

As per the file_put_contents documentation:

Tip
A URL can be used as a filename with this function if the fopen wrappers have been enabled.
See fopen() for more details on how to specify the filename.
See the Supported Protocols and Wrappers for links to information about what abilities the various wrappers have, notes on their usage, and information on any predefined variables they may provide.

file_put_contents is usually called to store data locally. For external storage, there are other means of safely storing data (you may want to look into a FTP client).

Check the return value of your call.

This function returns the number of bytes that were written to the file, or FALSE on failure.

My guess it is returns false.

If you want to store data on the same server, try a filesystem path (like "/someting/a.file")

Also, that post you linked to clearly said:

Use a local cache file, and just check the existence and modification time on the file before you use it. For example, if $cache_file is a local cache filename[...]

Alex Tartan
  • 6,736
  • 10
  • 34
  • 45
  • Thanks for your quick response. But I'm not sure if we misunderstand each other: I do want to store data locally. Therefore I created an empty cache.json file locally. And if I run the code above, the external URL is being called successfully, but the cache.json file remains empty. But my code should retrieve the API data **and** store it in the cache.json. But that second part isn't happening for some reason. Please note that I used "example.com" as example. Consider it my domain. – bauhausweb Jul 02 '17 at 15:22
  • 1
    If `$cache_file = "https://www.example.com/data/dataCache/cache.json";`, that's not a local filepath (even _if_ that points to a local file on your server). If it starts with "http", it's not local. Try to use something like `/tmp/cache.json` just to test it out. If that works, then you'll need update your `$cache_file` to something like `/var/www/project/data/dataCache/cache.json` – Alex Tartan Jul 02 '17 at 15:27
  • Also, use absolute paths (saw your post update and wanted to clarify this). Absolute paths start with '/' (or "C:" if you're on windows). So please make sure that either your relative path "path/to/my/cache.json" is corrent, or use an absolute one like "/path/to/my/cache.json" – Alex Tartan Jul 02 '17 at 15:36
  • Thanks a lot! The double-dots at "../data/dataCache/cache.json" did the trick. – bauhausweb Jul 02 '17 at 15:39
  • happy it turned out ok ;) – Alex Tartan Jul 02 '17 at 15:40
  • Do you know how I can test whether the chart data is being loaded from the API URL or the cache file? I looked a Developer Tools -> Sources and -> Network but I don't see if the external URL is called. – bauhausweb Jul 02 '17 at 15:49
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/148173/discussion-between-alex-tartan-and-bauhausweb). – Alex Tartan Jul 02 '17 at 15:50