Welcome Guest, Not a member yet? Register   Sign In
Database driven routes in CodeIgniter with caching
#1

[eluser]neillyons.co[/eluser]
A faster, simpler and easier solution to database driven routes in CodeIgniter.

Don't know what I'm on about? Read my previous post on database driven routes.

Prerequisites

* CodeIgniter (obviously ;-P )
* Datamapper

Step 1

Define 3 new methods in your routes model (..system/application/models/route.php).
Code:
function save()
{
    parent::save();
    $this->cache();
}

function delete()
{
    parent::delete();
    $this->cache();
}

/**
* Writes contents of database table to a cache file.
*
* @return void
*/
function cache()
{
    $data[] = "<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');";

    foreach($this->get()->all as $value)
    {
        $data[] = '$route["' . $value->route . '"] = "' . $value->controller . '";';
    }

    $output = implode("\n", $data);

    write_file(BASEPATH . "cache/routes.php", $output);
}
This will write the contents of the routes table as a PHP array to a file called routes.php in the cache folder (make sure this folder is writeable). This file would be deleted an rebuilt whenever an insert, update, or delete operation is performed on the routes database table.

Step 2

Insert the code below into the routes.php file ( ..system/application/configs/routes.php ) after the scaffolding trigger.
Code:
include_once BASEPATH . "cache/routes.php";
If anyone implemented the original solution let me know what you think of this.
#2

[eluser]Addow[/eluser]
Hi neillyons.info,

Yesterday I was struggling with the internationalization process of my CI application, specifically on the language based routing. I tried several methods to do it dynamically, but at the end I decided to use a modified cached database driven routing. I added an extra "language" field in the table, but that does not change anything to your approach.

I also tried other approaches (the no hooking/datamapper is one of them), but (as expected) the cached approach is a way faster than other database driven ones.

So I may conclude, I like this one very much, and both topics helped me a lot! Great work.
#3

[eluser]darrentaytay[/eluser]
Thanks for sharing this Nellyon, I think I will be using this as I'm very conscious of performance and this seems to be a great solution.

So just to clarify, if I have, 10,000 records which all have a route, I will have a table with 10,000 routes and a cache file with 10,000 routes?
#4

[eluser]neillyons.co[/eluser]
Yep, that seems right.
#5

[eluser]darrentaytay[/eluser]
I have just integrated this into my project - works a treat

Thanks!
#6

[eluser]boudou[/eluser]
i used your idea with doctrine 1.2 with update events on my routing table


Code:
public function postDelete($event){
        $this->_cache();
    }

      public function postInsert($event){
        $this->_cache();
    }


    function _cache() {

        $data[] = "<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');";

        $u = Doctrine::getTable('routes')->findAll();
        foreach ($u as $row) {
            $data[] = '$route["' . $row->route . '"] = "' . $row->controller . '";';
        }

        $output = implode("\n", $data);

        write_file(str_replace("\\", "/", FCPATH).APPPATH."cache/routes.php", $output);
    }


Thanks
#7

[eluser]Estu[/eluser]
Hi, i have a problem. I integrated this, but when I try to access to my website this error appears Cannot send session cache limiter - headers already sent (output started at /home/frinki/public_html/application/cache/routes.php:10)

edit: solved hehe
#8

[eluser]Unknown[/eluser]
Hi, I was considering using something of this kind (which I consider neat and fast!) for a project I'm working on, but it seems to me this is only one side of the problem. I mean, here we are translating world-facing SEO-friendly URLs to internal routes that CI (and developers) can handle and work with. But on the other hand, how should we do invert this translation, to find out what URL we should use for what the developer sees as "/some_controller/some_method"? I don't think we can flip array keys and values to the routes array and apply CI routing code as is, because there may be many-to-one relationships that can't be inverted, in other words, for one "internal" route as "/some_controller/some_method" there should be only one official world-facing URL...




Theme © iAndrew 2016 - Forum software by © MyBB