A couple of months ago I have started my adventure with CakePhp and as every Symfony’s developer I thought that any other framework except Symfony is a piece of crap. Day by day and step by step I began to realize that’s not so bad as it seemed to be in the beginning. Well, the second version of CakePhp still has a lot old-fashioned patterns, singletons or lack of tests, but I can live with that. I saw a lot of better or worse frameworks in my life. However, one module remains a bitter aftertaste – the router.
Let’s just look at the very basic things. Let’s start with new route declaration.
1 2 3 4 5 6 | Router::connect ( '/blog/:slug', array ( 'slug' => 'index', 'controller' => 'blog', 'action' => 'post', 'template' => 'white' )); |
It looks quite natural and shouldn’t make any unpredictable problems… well, shouldn’t. When I wanted to display an URL to the blog/:slug page in a View file I was struggling with additionals parameters and not found paths. As every developer I opened the declaration of connect method and tried to figure out what exactly happens inside. First impression was quite good – `public static function connect($route, $defaults = array(), $options = array()); `.
The author of Clean Code – Robert C. Martin emphasizes on the right naming. All methods, functions, classes or variables should tell you, literally, what responsibility they have. So, when I saw three parameters in connect method they seemed obvious – $route was for the URL, $defaults – filled the missing arguments by default values and $options – about additional information for my route.
Everything was clear and I couldn’t find out why my code cannot compose a proper URL until I caught the condition which was commented:
// keys that exist in the defaults and have different values is a match failure.
I was so wrong. In the result I’m pretty sure and, of course, I confirmed that, the code `Html->link($postName, array(‘controller’ => ‘blog’, ‘action’ => ‘post’, ‘slug’ => $slug)); ?>` will break, because we didn’t pass the argument template.
I believe that the second parameter in connect method should be called $requires. One confusing name took me 4 hours of my live and caused a lot of problems.
So, what can I do with this?
Extend! Extend the original routing by something what you really like. I’m huge fan of YML routing implemented in Symfony 2. It’s really simple, transparent and easy to read. Moreover, and what is the most important thing for me, each route has a name. So I can build every single URL without passing all defaults parameters, but focus only on mandatory as slug.
1 2 3 | blog_show: path: /blog/{slug} defaults: { controller: Blog, action: post } |
Looks better, right? Inspired by a presentation of @jakub_zalas – Symfony in the Wild I decided to start writing a bridge for routing between CakePHP and Symfony2 route component.
CakePhp Symfony Router
Ready to use Plugin can be found at https://github.com/piotrpasich/cakephp-symfony-routeror http://plugins.cakephp.org/p/1725-cakephp-symfony-router. Also, you can find there a exhaustive manual how to install and use this component. I have prepared a god base to eztend this for XML configuration files and annotations.
The main assumptions were to create a really simple in use system based on symfony router component to cover problems with I struggled. So, now you can call each route by name like this:
1 2 | <?php echo $this->SymfonyRouter->getPath('blog_post', array('slug' => $post->getSlug())); ?> <a href="<?php echo $this->SymfonyRouter->getPath('blog_post', array('slug' => $post->getSlug())); ?>"><?php echo $post->getSlug() ?></a> |
Conclusion
I really like the wise spectrum of available open source frameworks and platforms on the market. I learned Symfony, Zend, Kohana, CakePhp or even Drupal or WordPress. However, besides of the naming convention, used architecture or design patterns which can be more or less comfortable for me, sometimes I have to face a really huge problem which stops me for a couple of hours and I feel that I need to change that because every time I use it I will suffer (mentally).
Because the open source world emphasizes how the decoupling is important, it’s really easy to get my favourite component from one framework and put it into another. If I connect the framework with external module in a plugin – bridge, this should be easy to use for others. And I hope I did this.
Pingback: Today on the PHP Community … August 12, 2014 | PHP Community Magazine()
Pingback: Piotr Pasich: CakePHP with Symfony's2 router | facebooklikes()
Pingback: WebCoderPro » Weekly links for PHP developers #6: PHP Podcasts and how to hire PHPers()