1

I'm currently writing a custom route loader in Symfony 2 that will generate routes based on some configuration options defined in the main config file. The problem is that Symfony caches routes generated by custom routes loaders. Is there a way for me to update the cache when that config file changes?

I defined a configuration like this in app/config/config.yml

admin:
    entities:
        - BlogBundle\Entity\Post
        - BlogBundle\Entity\Comment

My route loader read the config file and generates some routes based on the entities. Now the problem is that once those routes are generated and cached by Symfony I can't change them unless I manually call php app/console cache:clear. What I mean is if I add an entity to the config:

admin:
    entities:
        - BlogBundle\Entity\Post
        - BlogBundle\Entity\Comment
        - TrainingBundle\Entity\Training

I will have to manually clear the cache again with php app/console cache:clear in order to create and cache the new routes. I want the routes cache to be invalidated if I change the config, so that a new request to the server will force the regeneration of the routes.

1
  • I had a similar issue stackoverflow.com/questions/39016123/… and finally i had to run the cache:clear command to make sure the routes were rebuilt. Commented Jan 31, 2017 at 14:57

1 Answer 1

1

Option 1
If your custom loader class can gain access to the kernel or the container (via DI), you could call the console cache clear command from that class.

E.g.

namespace AppBundle\MyLoader;

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

class MyLoader
{

    private $kernel;

    public function __construct($kernel)
    {
        $this->kernel = $kernel;
    }

    public function myFunction()
    {
        $application = new Application($this->kernel);
        $application->setAutoExit(false);

        $input = new ArrayInput(array(
           'command' => 'cache:clear',
           '--env' => 'prod',
        ));
        // You can use NullOutput() if you don't need the output
        $output = new BufferedOutput();
        $application->run($input, $output);

        // return the output, don't use if you used NullOutput()
        $content = $output->fetch();

        // return new Response(""), if you used NullOutput()
        return new Response($content);
    }
}

Ref: Call a Command from a Controller
Disclaimer before someone points it out; Injection the kernel/conatiner is not considered "best pratice", but can be a solution.

Option 2
You could also write you own console command that extends Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand that just calls the clear cache command.
Ref ; Call Command from Another

Option 3
This answer also gives you another option

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for your reply. The thing is that I want to force Symfony to process my route loader again when the config.yml file is changed so that it can cache new routes based on that config. How do I do that?
@ValeryMelou are you changing your config.yml on-the-fly? If so, the only way I can think of that might work is to delete the appProdProjectContainer* files located in var/cache/prod or var/cache/dev depending on what environment you are in
No, @rooneyl. I'm not changing the config on-the-fly. Take a look at my edit for a better understanding of what I'm trying to do.
@ValeryMelou, I'm not understanding the process very well. If you are manually editing the config file, I can't see when you can't run the cache clear command. If you are doing it programatically, then why won't either option of calling the cache clear command in code or deleting the appProdProjectContainer files work for you?
Just thought that it my be easier for the end user to not have to clear the cache every time he changes to config file which seems to be the only solution for this right now. I'll leave it like that for now. Thanks for your help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.