Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

divinulledivi's avatar

How to create a php file caching mechanism?

I applied for a Junior PHP Developer position and got a test that I need to finish today. The idea is to get data from their API and cache it for a set amount of time. I got the data, that part was easy, but I'm having trouble writing the set method for caching (I need to use an interface they supplied).

I know they want to test my knowledge of OOP and I thought I have the basics down but I guess this is too advanced for me. I have rewatched PHP OOP videos (inheritance, messages 101..) at least five times and I still don't fully get it.

Am I aiming too high and not ready for a job?

Any help would be greatly appreciated. Here's the code I have so far. Just to make it clear, I don't want an exact answer but maybe some pointers in the right direction? Thanks.

$result = $response->getBody(); //Data that needs to be cached
$jsonToArray = json_decode($result, true); //Needs to be stored as an array

interface CacheInterface 
{
    public function set(string $key, $value, int $duration);
    public function get(string $key);
}



class CacheController 
{
    private $cache;

    public function __construct(CacheInterface $cache) {
        $this->cache = $cache;
    }
}

class Cache implements CacheInterface 
{
    
    public function set(string $key, $value, int $duration = 60*5) {
        //key->filename?
        //value->json
    }


    public function get(string $key) {
        //if file exists, return file
        //else return null
    }

}

0 likes
9 replies
crnkovic's avatar

Um... file_put_contents and file_get_contents? Just serialize data and put it in the file... When receiving the file, check the expiration date. You could store the expiration date in the filename. Or in the beginning of the file. :)

Something like $key . $expirationTimestamp

divinulledivi's avatar

@crnkovic, I was also thinking about file_put_contents but I wasn't sure. Also didn't know how to check the time, will try your way. Also, did I guess right - the $key argument is supposed to be the file name?

A few other questions - as I mentioned before I'm not too good with OOP yet. The code I wrote is a mixture from Laracasts videos and some tutorials I found. (One of the requirements is that the interface should be constructor-injected in to the service). Can you explain the need for a CacheController? Can't I do the same in the Cache object?

divinulledivi's avatar

I got it working (kind of).

Since the interface requires a $duration argument in the set method, I added it as a property. If I run the set function once and then the get function separately, the $duration property is empty. If I hardcode the duration it works just fine. What am I doing wrong here?


class Cache implements CacheInterface 
{
    private $duration;
    
    public function set(string $key, $value, int $duration) 
    {
        $this->duration = $duration;
        file_put_contents($key, $value);
    }


    public function get(string $key) 
   {

        if (file_exists($key) && time() - filemtime($key) < $this->duration) {
            $fileContents = file_get_contents($key);
            $output = unserialize($fileContents);
            var_dump($output);
        } else {
            echo 'cache expired';
            return null;
        }
    }


}

//Instantiate the Cache class
$file = new Cache;

//$file->set('result', $resultFinal, 60*5);

$file->get('result'); //Returns null because $duration is empty once the set method is commented out
yoeriboven's avatar

You mean you first run the set method, then comment it out and run the get method?

In that case it is because a new instance is created. Don't (only) store the duration on the object. Also store it in the file or as the filename.

crnkovic's avatar

If you store a timestamp in the filename, then you can check for duration like that.

When storing:

$filename = $key . (time() + $duration)

When getting a file: left trim the $key from the filename, rest of the filename is the timestamp after which the cache has expired.

if ($timestamp < time()) {
    // expired
}
divinulledivi's avatar

@CRNKOVIC - When exactly do I trim the $key? I tried this before but realized I can't call the get() method without the timestamp.

For example, I have a file named result1552492419, how would I call it with the get() method?

crnkovic's avatar

You could then simply store it in the beginning of file contents.

krishna812's avatar

Hello @divinulledivi

I got stuck in the same. It would be great if you could help me in retriving the response-body using API key.

Thanks in advance

Please or to participate in this conversation.