-3

This is some working code that I wrote to call a JSON file and cache it on my servers.

I'm calling the cached file. If the file exists I use json_decode on it. If the file doesn't exist I then call the JSON and decode that. Then after calling the JSON url, I write the contents to the cached file url.

$cache = @file_get_contents('cache/'.$filename.'.txt');

 //check to see if file exists:
if (strlen($cache)<1) {

    // file is empty
    echo '<notcached />';
    $JSON1= @file_get_contents($url);

    $JSON_Data1 = json_decode($JSON1);

    $myfile = fopen('cache/'.$filename.'.txt', "w");
    $put = file_put_contents('cache/'.$filename.'.txt', ($JSON1));

} else {

    //if file doesn't exist:
    $JSON_Data1 = json_decode($cache);
    echo '<cached />';
}

Instead of only using if (strlen($cache)<1) {, is there a way that I can check the age of the $filename.txt and if it's older than 30 days grab the JSON url in the else statement?

Kasia Gogolek
  • 3,374
  • 4
  • 33
  • 50
Michael d
  • 305
  • 2
  • 16
  • You could use `filemtime()` to check the last modified time (http://php.net/manual/en/function.filemtime.php). – Nigel Ren Mar 01 '18 at 14:19
  • filetime does seem like the correct command. Do you know how I might write an if statement that if filetime > 30 days old { ? – Michael d Mar 01 '18 at 14:21
  • 1
    `if (filemtime('cache/'.$filename.'.txt') > strtotime('now -30 day')) {}` Would do it. Also checking on `file_exists('cache/'.$filename.'.txt')` is better than trying to load it in with error suppression. – IncredibleHat Mar 01 '18 at 14:23
  • 1
    Why do you `fopen()`? – axiac Mar 01 '18 at 14:42
  • thanks @IncredibleHat ! NigelRen's spinoff of your recommendation works. Unfortunately, I think I'm going to delete this question though since everyone seems to think it was worth downvoting. Wish I knew why my questions often get downvotes. I think this question and all of your answers will be really helpful to people coming in from Google search, but ok... – Michael d Mar 01 '18 at 15:23
  • ... it seemed a fine enough question. I don't know. The original code was rough, and obviously not a right way to do it... but thats why you were asking. – IncredibleHat Mar 01 '18 at 15:25

2 Answers2

2

You can use something like

$file = 'cache/'.$filename.'.txt';
$modify = filemtime($file);
//check to see if file exists:
if ($modify == false || $modify < strtotime('now -30 day')) {
    // file is empty, or too old
    echo '<notcached />';
} else {
    // Good to use file
    echo '<cached />';
}

filemtime() returns the last modified time of the file, the if statement checks that the file exists (filemtime returns false if it fails) or the file was last modified more than 30 days ago.

OR... to check if the file exists or too old (without warnings)

$file = 'cache/'.$filename.'.txt';
if (file_exists($file) == false || filemtime($file) < strtotime('now -30 day')) {
    // file is empty, or too old
    echo '<notcached />';
} else {
    // Good to use file
    echo '<cached />';
}
Nigel Ren
  • 56,122
  • 11
  • 43
  • 55
  • Thanks Nigel! I tested this with if (file_exists($file) == false || filemtime($file) < strtotime('now -1 minute')) { and it looks like it works! Unfortunately, I'll probably delete this question since everyone seems to think it was worth downvoting for some reason. Wish I knew why my stuff gets downvoted – Michael d Mar 01 '18 at 15:22
  • 1
    I gave up worrying about down-voting, I used to ask why and didn't usually get anything helpful. Most important thing is you've solved this problem. – Nigel Ren Mar 01 '18 at 15:36
2

I've used a simple file cache class in my previous projects, I think that should help you. I think it's easy to understand, the cache time is in seconds and the setFilename function cleans the filename in case it contains invalid characters.

<?php

class SimpleFileCache
{
    var $cache_path = 'cache/';
    var $cache_time = 3600;
    var $cache_file;

    function __construct($name)
    {
        $this->setFilename($name);
    }

    function getFilename()
    {
        return $this->cache_file;
    }

    function setFilename($name)
    {
        $this->cache_file = $this->cache_path . preg_replace('/[^0-9a-z\.\_\-]/', '', strtolower($name));
    }

    function isCached()
    {
        return (file_exists($this->cache_file) && (filemtime($this->cache_file) + $this->cache_time >= time()));
    }

    function getData()
    {
        return file_get_contents($this->cache_file);
    }

    function setData($data)
    {
        if (!empty($data)) {
            return file_put_contents($this->cache_file, $data) > 0;
        }
        return false;
    }
}

It can be used like this.

<?php

require_once 'SimpleFileCache.php';

$cache = new SimpleFileCache('cache.json');
if ($cache->isCached()) {
    $json = $cache->getData();
} else {
    $json = json_encode($someData); // set your cache data
    $cache->setData($json);
}

header('Content-type: application/json');
echo $json;
xander
  • 1,780
  • 9
  • 16