Learn how to create a console command for Silex to clear the cache.

How to clear the cache with the CLI in a Silex Project

For a developer that already works with Symfony and suddenly have to work with a Silex based project, although most of the things are the same, there obviously things that don't. One of the most tedious tasks in Silex, for example when you implement Twig is the need of clearing the cache, however this must be made manually, removing the content of the /cache folder. As mentioned, if you come from a pure Symfony environment, you know that there's already a CLI command in the project namely cache:clear that does this for you. Silex doesn't have such a feature, however you can implement it by yourself, so you won't need to delete the content of the cache folder by yourself everytime you are out of the development environment!

In this article, we'll show you how to easily add the cache:clear command to your Silex application.

Important

In this tutorial we assume that you already implemented the console.php file for silex where you can register new console commands, in case you don't, please refer to the console component of Symfony for more information.

1. Create the cache:clear command

We'll provide you with the command to clear the cache folder of your Silex project, however you need to know how to load the command in your application. This is usually made (following the default Silex Skeleton structure) in the console.php file of your project, where you should find already a Symfony Console Application. If not, you can create it. The following example adds the cache:clear command creating a basic console application in the console.php file:

<?php

// src/console.php

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Finder\Finder;

// Your application, this is just an example of initialization, this should be different in your app ...
$console = new Application('My Silex Application', 'n/a');
$console->getDefinition()->addOption(new InputOption('--env', '-e', InputOption::VALUE_REQUIRED, 'The Environment name.', 'dev'));
$console->setDispatcher($app['dispatcher']);
$console
    ->register('my-command')
    ->setDefinition(array(
        // new InputOption('some-option', null, InputOption::VALUE_NONE, 'Some help'),
    ))
    ->setDescription('My command description')
    ->setCode(function (InputInterface $input, OutputInterface $output) use ($app) {
        // do something
    })
;

// Register the cache:clear command !
$console
->register('cache:clear')
->setDescription('Clears the cache')
->setCode(function (InputInterface $input, OutputInterface $output) use ($app) {
    if (!isset($app['cache.path']))
    {
         $output->writeln(sprintf("<error>ERROR:</error> could not clear the cache: <info>\$app['cache.path']</info> is not set.", 'cache:clear'));
         return false;
    }
    $cacheDir = $app['cache.path'];
    $finder = new Finder();
    $finder
        ->in($cacheDir)
        ->notName('.gitkeep')
    ;
    
    //--- from Filesystem::remove()
    $remove = function ($files, $recurse) {
        $files = iterator_to_array($files);
        $files = array_reverse($files);
        foreach ($files as $file) {
            if (!file_exists($file) && !is_link($file)) {
                continue;
            }
            if (is_dir($file) && !is_link($file)) {
                $recurse(new \FilesystemIterator($file), $recurse);
                if (true !== @rmdir($file)) {
                    throw new \Exception(sprintf('Failed to remove directory %s', $file));
                }
            } else {
                // https://bugs.php.net/bug.php?id=52176
                if (defined('PHP_WINDOWS_VERSION_MAJOR') && is_dir($file)) {
                    if (true !== @rmdir($file)) {
                        throw new \Exception(sprintf('Failed to remove file %s', $file));
                    }
                } else {
                    if (true !== @unlink($file)) {
                        throw new \Exception(sprintf('Failed to remove file %s', $file));
                    }
                }
            }
        }
    };
    
    $remove($finder, $remove);
    $output->writeln("Cache succesfully cleared!");
    return true;
})
;

return $console;

Save the changes to the file and proceed with the next step.

2. Define the cache path globally

Otherwise you will find the exception "ERROR: could not clear the cache: $app['cache.path'] is not set." if you try to run the command without following this step. To define the cache.path property, you may want to do it in the app.php file of your project, simply assign the new key to the $app variable with the path to the cache folder of your Silex project:

Note

According to the structure of your project, the path may change, so be sure to provide the correct path.

// Define the cache.path property to the cache directory of your Silex Project.
// app.php
$app['cache.path'] = __DIR__.'/../var/cache';

3. Test the command

As last step, after saving changes you will be able to run your command from your terminal on the root folder your project:

php bin/console cache:clear

Once you run the command from the terminal, you will see the "Cache succesfully cleared" message, assuming that everything went right.

Happy coding !


Senior Software Engineer at Software Medico. Interested in programming since he was 14 years old, Carlos is a self-taught programmer and founder and author of most of the articles at Our Code World.

Sponsors