We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Help with Phalcon\Cache and Phalcon\Cache\Backend\Apc

New to Phalcon and need some help in using Phalcon\Cache and Phalcon\Cache\Backend\Apc.

1) Phalcon\Cache\Backend\Apc - What does the "prefix" option actually do? Even though I create a cache with prefix set to 'cache', I am still able to just use the key without the prefix to get data from cache.

2) What is the "tracking" option for and does it apply to Backend\Apc? This option is not documented anywhere, but was in the code example for Memcached on GitHub incubator.

3) Where exactly should the cache code be if global, static data needs to be cached? Should it be under dependency injector in services.php? I want to read a static catalog (e.g restaurant menu) once a day from the database and have it cached for all users to access. Currently, I have something like this:

$di->set('mydailyrefreshcache', function() {

    $frontendcache = new Phalcon\Cache\Frontend\Data ....

    $cache = new Phalcon\Cache\Backend\Apc ($frontendcache, array(
        'prefix' => 'cache'
    ));

    if (!$cache->exists('my-key')) {
        $arr = Catalog::find();
        $cache->save('my-key', $arr);
    }
});

Thanks for the help!



98.9k
Accepted
answer

1) Phalcon\Cache\Backend\Apc - What does the "prefix" option actually do? Even though I create a cache with prefix set to 'cache', I am still able to just use the key without the prefix to get data from cache.

It automatically prefixes all the keys used, this to prevent collisions to existing values in APC

2) What is the "tracking" option for and does it apply to Backend\Apc? This option is not documented anywhere, but was in the code example for Memcached on GitHub incubator.

It does not apply to APC

3) Where exactly should the cache code be if global, static data needs to be cached? Should it be under dependency injector in services.php? I want to read a static catalog (e.g restaurant menu) once a day from the database and have it cached for all users to access. Currently, I have something like this:

The easiest way is implement a modelsCache service and use it as follows:

<?php

//Set the models cache service
$di->set('modelsCache', function() {

    //Cache data for one day by default
    $frontCache = new \Phalcon\Cache\Frontend\Data(array(
        "lifetime" => 86400
    ));

    //Memcached connection settings
    $cache = new Phalcon\Cache\Backend\Apc ($frontendcache, array(
        'prefix' => 'cache'
    ));

    return $cache;
});

Then in your models pass a 'cache' parameter to tell the ORM the resultset must be cached:

$products = Products::find(array(
    "cache" => array("key" => "my-cache")
));

https://docs.phalcon.io/en/latest/reference/models-cache.html#caching-resultsets



4.3k

Thanks, this is very helpful! Just to confirm, will passing the cache parameter in the find() method automatically return results from the cache rather than DB if the cache is still alive? Or should I be checking if the key "my-cache" exists in modelsCache?

//Some action handler in a controller
public function catalogAction() {

    if (!$this->modelsCache->exists('my-cache')) {
        $products = Catalog::find(array(
            "cache" => array("key" => "my-cache")
    ));
    }
}


4.3k

I just tried this with and without the modelsCache->exists() check. It works without the check. The model code seems to handle this. So now my code simply looks like it was suggested in the answer:

//Some action handler in a controller
public function catalogAction() {

    $products = Catalog::find(array(
        "cache" =>  array("key" => "my-cache")
    ));
}