When it comes to web development, performance is one of the critical elements that influence the success of an application. Developers focus on improving response times and overall speed to enhance the user experience.

When a user visits a website or interacts with a web application, various resources such as images, scripts, and database queries are requested from the server. Retrieving these resources can sometimes be time-consuming, especially if they require complex processing or querying a database.

To speed up this process and improve overall performance, developers implement caching mechanisms. When data is first requested, it’s stored in a cache. Then, when subsequent requests for the same data are made, the application can retrieve it from the cache instead of fetching it from the original source. This reduces the time it takes to serve the content to the user because accessing data from the cache is typically much faster than retrieving it from the original source.

This article is a follow-up to the previous article where we tackled the caching topic.

In this article our focus will be on enabling the dot-cache component and effectively implementing caching in DotKernel Admin.

Installation

Run the following command in your project directory:

composer require dotkernel/dot-cache

After installing, add the Dot\Cache\ConfigProvider::class class to your configuration aggregate (config/config.php).

Before we continue with the configuration process we need to know a few things about how and where the data is stored.

The dotkernel/dot-cache component is a wrapper that sits on top of symfony/cache. It currently supports two adapters and can store data in two distinct locations:

  1. array – stores data in-memory
  2. filesystem – stores data on local disk files

1. Storing data in-memory is the fastest and sometimes the cheapest caching mechanism, but it also comes with down-sides. Storing everything in the RAM memory is not the best idea when your application is running on a low memory system. In this case you should consider using the filesystem mechanism.

2. The second caching mechanism involves storing data into files on the local disk, known as the filesystem option. While this option may be slightly slower than the first one, it provides a more persistent storage solution.

Feel free to explore and use other adapters from symfony/cache by checking the official documentation.

Configuration

In config\autoload\doctrine.global.php, in the doctrine.configuration.orm_default key add the following entry:

'result_cache'       => 'filesystem',
'metadata_cache'     => 'filesystem',
'query_cache'        => 'filesystem',
'hydration_cache'    => 'array',
'second_level_cache' => [
    'enabled'                    => true,
    'default_lifetime'           => 3600,
    'default_lock_lifetime'      => 60,
    'file_lock_region_directory' => '',
    'regions'                    => [],
],

Next, under the doctrine key add the following items:

'cache' => [
    'array' => [
        'class'     => \Dot\Cache\Adapter\ArrayAdapter::class,
    ],
    'filesystem' => [
        'class'     => \Dot\Cache\Adapter\FilesystemAdapter::class,
        'directory' => getcwd() . '/data/cache',
        'namespace' => 'doctrine',
    ],
],

The result is that the metadata and query cache will be stored in the data/cache/doctrine folder and the hydration cache will be stored in-memory.

Each system is unique, requiring customized configurations. Make sure to identify the specific configuration requirements for your application.

Doctrine cache is divided into 4 different types: 

  • result_cache
  • metadata_cache
  • query_cache
  • hydration_cache
Result cache

The result cache can be used to store the results of your queries, enabling Doctrine to avoid querying the database or hydrating the data again after the initial retrieval.

 

Metadata cache

Parsing your class metadata on every request is inefficient. Instead, it’s advisable to cache this information using one of the available cache adapters.

 

Query cache

In a production environment, it’s strongly recommended to cache the resulted DQL query into its SQL equivalent. Since the query doesn’t change unless the DQL query itself changes, it’s unnecessary to parse it multiple times.

Hydration cache
Doctrine hydration cache is a feature that stores the results of data hydration, which is the process of converting raw database data into usable objects or arrays. By caching these results, it avoids repeating the hydration process for repeated queries, improving performance.
How to use

To enable caching for entities, need to add the  #[ORM\Cache] attribute like in the following example:

#[ORM\Entity(repositoryClass: AdminRepository::class)]
#[ORM\Table(name: "admin")]
#[ORM\Cache(usage: "NONSTRICT_READ_WRITE")]
class Admin extends AbstractEntity implements AdminInterface
{
}

For further details about the cache mode please refer to the official documentation.

When querying data, you can have Doctrine cache your results. You do this by calling the setCacheable method on the query builder.

$this->getQueryBuilder()
->select('admin')
->from(Admin::class, 'admin')
->setCacheable(true)
->getQuery()
->getResult();

Caching is not limited to entities alone. Objects can be cached too. Check the basic cache usage for this purpose.

In conclusion, cache plays a vital role in optimizing system performance and improving user experience by storing frequently accessed data. As technology continues to evolve, caching mechanisms will remain an integral part of modern computing architectures, driving faster access to data and smoother user interactions across various digital platforms.


Looking for PHP, Laminas or Mezzio Support?

As part of the Laminas Commercial Vendor Program, Apidemia offers expert technical support and services for:

  • Modernising Legacy Applications
  • Migration from any version of Zend Framework to Laminas
  • Migration from legacy Laminas API Tools (formerly Apigility) to Dotkernel API
  • Mezzio and Laminas Consulting and Technical Audit
  • Leave a Reply

    Your email address will not be published. Required fields are marked *

    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>