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

Models cache empty

The result is empty and is cached, causing the function to always return empty data before the cache expires. If the result is empty, can it not be cached

function getByEmail(string $email)
{

    $key = 'user_email_' . $email;

    $result = UserModel::findFirst(

        [
            'conditions' => 'email = ?0',
            'bind'       => [$email],
            'cache'      => ['key' => $key]
        ]

    );

    return $result;

}

There are only two hard things in Computer Science: cache invalidation and naming things.

-- Phil Karlton

Here is how I handle this problem in most of my projects, not the best, but you can use it as an idea and improve ;)

All my models extend a BaseModel which has clearCacheFiles method:

private function clearCacheFiles()
{
    // Clear Filesystem cache
    $modelNamespaces = explode('\\', get_class($this));
    $model = strtolower(end($modelNamespaces));
    $path = $this->getDI()->getConfig()->site->path->cache . 'queries/';
    \Helpers\Files::deleteFileLike($path . $model .'-');
}

public function afterSave()
{
    $this->clearCacheFiles();
}

public function afterDelete()
{
    $this->clearCacheFiles();
}

How does it work? Every time a model is saved, deleted and so on the clearCacheFiles method is called, which deletes the actual cache files. Whenever I need custom cache handling for a model, i just overwrite the clearCacheFiles in the desired model.

For example, the cache key for a query to fetch all products would look something like products-all, the important part in my case is that I use the model name for cache "prefix" to automate deletion.

  • Specific product products-one-43
  • Complex search: products-search-'. md5(serialize($params)) Where $params can hold any amount of search parameters
  • Your example: [email protected]

I don't mean to say how to automatically delete the cache.

edited May '18
function register($name)
{

    if (getByUserName($name)) {

        exit('The username has already existed');

    }

    $user = new UserModel;

    $user->name = $name;

    return $user->save();

}

function getByUserName($name)
{

    $key = 'user_name_' . $name;

    $result = UserModel::findFirst(

        [
            'conditions' => 'name = ?0',
            'bind'       => [$name],
            'cache'      => ['key' => $key]
        ]

    );

    return $result;

}

//User name is unique.

register('hello');  // It's reg success.

register('hello'); // Fatal error

Registering the same username for the second time will generate a fatal error.

Because at the time of my first registration, although the 'hello' username does not exist, it is also cached.

So getByUserName still returns null on the second call.

When the database does not exist, phalcon also caches empty data.

@nikolay-mihaylov

Thats the intended behavior. You have two options:

  1. Delete cache file after creating user.
  2. Do not use cache for those type of query checks.