1
votes

I am integrating a legacy Zend Framework 1 (ZF1) application and a Symfony 3.2.6 (SF) application. In a nutshell how it works is:

  • The session management, the login page (unique entrypoint) and a lot of stuff are managed by the ZF1 application and ZF1 itself
  • There is not call to any Zend controller, templates, helpers or any other from SF side

As an example: - http://localhost/login => will be managed by ZF1 - http://localhost/sf/quote => will be managed by SF (the key is the /sf/ in the URL)

This mean I have a rule in the Apache VH saying: each request with /sf/* on the URL sent it to app.php|app_dev.php which is Symfony otherwise it'll bypass this rule and it'll go to ZF1 directly.

Having that first thing I do is login in the application using legacy ZF1 application. After login successfully I redirect to the dashboard an a NavigationController.php is invoked from the main.phtml layout using the following code: $this->action('buildallmenu', 'navigation');.

In such code the menu gets generated from DB and then using the code below I am trying to cache it since I don't need to and I don't want to access the DB once again from ZF1 nor from SF.

use Predis\Client;
use Symfony\Component\Cache\Adapter\RedisAdapter;

$cached_items = [
    'main_nav'   => $main_nav,
    'sub_nav'    => $sub_nav,
    'footer_nav' => $footer_nav,
    'view_as'    => $view_as,
];

$redisConnection = new Client('tcp://cache_server:6379');
$cache           = new RedisAdapter($redisConnection);
$menu            = $cache->getItem('mmi_menus_'.session_id());

if (!$menu->isHit()) {
    $menu->set($cached_items);
    $cache->save($menu);
}

return $menu->get();

Why session_id() because the menu is "unique" per user so makes sense to append the session_id() to the Redis cache item.

From there I am seeing the $cached_items var populated with the proper content and it's saved to the Redis.

Now the way I access to a Symfony controller is how I explained before: "by accessing a URL". Let's say I called a URL as: http://localhost/sf/quote this will execute the rule and redirect to app_dev.php which means I am on Symfony now.

First thing I did was check the session_id() (printing the session_id() value) and compare against the value created by ZF1 and they match.

The SF base template call a controller as: {{ render(controller('CommonBundle:Setup:GenerateMenuItems')) }}. This is the content of the function called from the template:

public function GenerateMenuItemsAction()
{
    $menu = $this->get('mmi_pool')->getItem('mmi_menus_'.session_id());

    dump('mmi_menus_'.session_id());

    if ($menu->isHit()) {
        return $this->render(
            'CommonBundle:Layout:menu.html.twig',
            ['menu' => $menu->get()]
        );
    }

    return new  Response();
}

mmi_pool is a service which defintion is as follow:

mmi_pool:
    parent: cache.adapter.redis
    tags:
      - name: cache.pool
        namespace: ''

How cache is configured at config.yml?

framework:
    cache:
        default_redis_provider:  redis://%redis_host%:%redis_port%

Update

I have found that when I login for first time this piece of code is not executed:

if (!$menu->isHit()) {
    $menu->set($cached_items);
    $cache->save($menu);
}

I am not sure the why. That's causing the cache to store the wrong items and therefore show the wrong items on SF.

what I am doing wrong here? I know caching is tricky but certainly I am missing something here

1
I'd echo out the key you are creating, on both sides, and also taking a look for them after the cache-save from inside Redis itself. Seeing exactly what is happening, as opposed to what you think happens is often enlightening. - Alister Bulman
Use redis-cli to make a keys * query and then a get query against any key to be sure what is being stored. Where are you translating the stores value to an object? - Carlos
@AlisterBulman I've added such information but as you can see still not showing anything on Symfony side - ReynierPM
@Carlos do I need to translate them into a object? What for? I am sending an array I would expect to get an array :-\ I get lost in this one - ReynierPM
I usually store like $redis->save('key',json_endode($vaue)); and retrieve json_decode($redis->getItem('key'); so with any kind of data type it works. - Carlos

1 Answers

2
votes

First time $menu is null, but it always null because of that code: if (!$menu->isHit()) { return ... You exit controller with return statement.

if (!$menu->isHit()) {
    $menu->set($cached_items);
    $cache->save($menu);
}

return $menu->get();