13

In the admin panel of my project, I programmed the ability to change the database name to use. I wrote the new database name in the parameters.ini, and after that the cache had to be cleaned to load the new config.

What is the best way to clean the cache without running the console command?

Or is there another best practise how to change the current db.

nbro
  • 15,395
  • 32
  • 113
  • 196
Johni
  • 2,933
  • 4
  • 28
  • 47

7 Answers7

17

You can use the console command via exec():

exec("php /my/project/app/console cache:clear --env=prod");

Or simply empty the cache/ folder if you don't want to use the console command.

Samy Dindane
  • 17,900
  • 3
  • 40
  • 50
  • 1
    Yes, thats my plan B nut i can't perform a warmup. – Johni May 30 '12 at 12:24
  • What do you mean by a warmup? – Samy Dindane May 30 '12 at 12:24
  • 1
    The behaviour, the console command does (prefilling the cache). – Johni May 30 '12 at 12:26
  • Okay, how can't you *perform* it? – Samy Dindane May 30 '12 at 12:27
  • The problem is, that at the moment the cache folder is deleted the script is still running and needs stuff from it. And it gets only filled at the next request. So i get a exception: PDOException: SQLSTATE[HY000] [14] unable to open database file – Johni May 30 '12 at 12:31
  • 2
    Then execute the Symfony2 command. `exec()` will stop the script's execution until the command finishes. – Samy Dindane May 30 '12 at 12:35
  • Ok, i wrote a litte wsrapper service to run a command. It serems to work. Thanks. – Johni May 30 '12 at 12:50
  • Ok, i thougt it worked but there is another problem. After cleaning the cache the cache directory is set to 'prod_new' in the cache. But the actual cache directory is 'prod'. Without warming up it seems to work, but all in all it's not a satisfying solution. – Johni May 30 '12 at 13:11
  • I suggest then to clear the cache directory with exec: `exec("rm -rf /my/project/app/cache/*");` - Unless you find a fix to your problem. – Samy Dindane May 30 '12 at 13:47
10

You can call this action to clear a cache:

/**
 * @Route("/cache/clear", name="adyax_cache_clear")
 */
  public function cacheClearAction(Request $request) {
    $input = new \Symfony\Component\Console\Input\ArgvInput(array('console','cache:clear'));
    $application = new \Symfony\Bundle\FrameworkBundle\Console\Application($this->get('kernel'));
    $application->run($input);
   }
Pacufist
  • 101
  • 1
  • 3
  • 1
    How would you go about clearing the production environment? e.g. using --env=prod – Mirage May 28 '14 at 12:49
  • Can you provide context for what file you would put this function into? And do you need to add a custom route in your own config/routing.yml file or does the annotation magically do that? – Chadwick Meyer Jun 10 '14 at 22:44
  • The annotation provided gave an error (something about missing 'use' statement), so I'm sure I just don't understand how that works and that some namespace needs to be referenced in the header for @Route. But when I added this function to it's own controller and created my own route, this worked. Thanks. (y) – Chadwick Meyer Jun 10 '14 at 22:57
  • The necessary namespace is `Symfony\Component\Routing\Annotation\Route`. Put it in a use statement under the controller's namespace declaration. – tvanc Oct 02 '14 at 16:42
  • @Mirage To clear the prod env you would need to replace $this->get('kernel') by new \AppKernel('prod', false) (sorry for the up) but I've also posted an answer a bit cleaner than this one – Tofandel Jun 07 '17 at 12:25
4

Most recent best way (2017). I'm creating this in controller:

use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Output\BufferedOutput;

/**
 * Refresh Cache
 */
public function refreshRoutes()
{
    $kernel = $this->container->get('kernel');

    $application = new Application($kernel);
    $application->setAutoExit(false);

    $input = new ArrayInput([
        'command' => 'cache:clear',
        '--env'   => 'prod',
    ]);

    $output = new BufferedOutput();
    $application->run($input, $output);
}
HelpNeeder
  • 6,383
  • 24
  • 91
  • 155
  • 2
    Are you using this code? Somehow the system does not take the environment into account for me with this exact code (neither the `--no-debug` flag) – kero May 31 '17 at 10:06
  • I think I had injected container service into the script I've used. – HelpNeeder May 31 '17 at 18:06
  • 2
    @kero I've looked into the CacheClearCommand.php file and found that the command is not actually using the --env parameter, it's actually using the current kernel to get the cache folder and everything so what you would need to do to clear the prod cache would be to add this : $this->container->set('kernel', new \AppKernel($env, true)); to the code, I will edit the answer with the correction – Tofandel Jun 07 '17 at 12:03
1

My working action with rendering of Success page. It clear the cache at shutdown.

public function clearCacheAction(Request $request)
{ 
    $dir = $this->get('kernel')->getRootDir() . '/cache';
    register_shutdown_function(function() use ($dir) {
        `rm -rf $dir/*`;
    });
    return $this->render('SomeBundle:SomePart:clearCache.html.twig');
}

Note, you lose sessions if you didn't configure session: in config.yml.

PLoginoff
  • 11
  • 1
  • This code should be identical to ``cache:clear --no-warmup`` as it only deletes the cache, but does not warm it up. – JimmyBlu Nov 06 '14 at 15:52
1

@HelpNeeder's answer is good but the ClearCache command is not using the --env option given. It is instead using the current kernel the application is running on.

So for it to work with another environnement than the environnement you call the controller from, you need to tweak the code a bit (I can't edit his answer, it's saying the edit queue is full) so here is a more complete answer:

//YourBundle:YourController

use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Output\BufferedOutput;

public function clearCacheAction($env = 'dev', $debug = true)
{
    $kernel = new \AppKernel($env, $debug);

    $application = new Application($kernel);
    $application->setAutoExit(false);

    $input = new ArrayInput([
        'command' => 'cache:clear'
    ]);

    $output = new BufferedOutput();
    $application->run($input, $output);

    return $this->render('someTwigTemplateHere', array('output' => $output->fetch()));
}

Then you configure the routes :

cache_clear_dev:
    path:     /_cache/clear/dev
    defaults: { _controller: YourBundle:YourController:clearCache, env: 'dev', debug: true }

cache_clear_prod:
    path:     /_cache/clear/prod
    defaults: { _controller: YourBundle:YourController:clearCache, env: 'prod', debug: false }

And you can now output the result of the command using {{ output }} in your twig template.

If you have an access control, don't forget to set the permission for this route to a SUPER_ADMIN or something, you wouldn't want anyone other than an admin able to clear the cache.

Tofandel
  • 3,006
  • 1
  • 29
  • 48
0

i'm clearing cache this way:

$fs = new Filesystem();
$fs->remove($this->getParameter('kernel.cache_dir'));

https://gist.github.com/basdek/5501165

Stan Fad
  • 1,124
  • 12
  • 23
  • This regulary fails for me with `Failed to remove directory "/var/www/app/var/cache/prod": rmdir(/var/www/app/var/cache/prod): Directory not empty.` so it does not look like a good option to me. Multiple processes are using the directory in parallel so you can not just remove it. – cebe Dec 12 '17 at 06:53
-1

Although his answer is more/less obsolete, his recommendation is still useful today:

The answer is amazingly quite simple.

All cache files are stored in a single cache/ directory located in the project root directory.

So, to clear the cache, you can just remove all the files and directories under cache/. And symfony is smart enough to re-create the directory structure it needs if it does not exist.

Fabien Potencier, November 03, 2007

So following his recommendation I wrote a function that does exactly that:

/**
* @Route("/cache/clear", name="maintenance_cache_clear")
*/
public function cacheClearAction(Request $request)
{
    $kernel=$this->get('kernel');

    $root_dir = $kernel->getRootDir();

    $cache_dir = $kernel->getCacheDir();

    $success = $this->delTree($cache_dir);

    return new Response('...');
}

where delTree($dir_name) could be any function that removes recursively a directory tree. Just check the PHP rmdir function's User Contribution Notes, there are plenty of suggestions.

Eugen Mihailescu
  • 3,553
  • 2
  • 32
  • 29