Skip to content
Bill Zhao edited this page Apr 7, 2015 · 23 revisions

Would you like to serve up already-existing HTML and PHP pages inside a CI context? Migrate a site to CI perhaps?

This is how I did it with a minimum of fuss. And no messing around in htaccess files - pure PHP/CI solution.

Using this technique, you can "embed" your old site INSIDE CI and serve your old pages (HTML and PHP) as CI view files.

EDIT: 20110625 updated controller initialization code to work properly with CI 2.0.2.

One brute force way to migrate a site to CI is to write a controller method for every static page. But, if you are using CI already, then you probably like to find efficient ways rather than brute force ways.

Instead of mapping pages to controllers by hand, this code uses _remap() to handle incoming URIs. It uses a base controller that you extend. The base controller first checks if there is a controller method anywhere in the child or parent class. If there is not a controller method, it checks the filesystem for a matching view file. If there is a matching view file, then it loads it through the normal CI load->view() method. If there is no view file, you get the normal CI 404 error.

Drop this base controller in place with a "skeleton" child class (optional but recommended) and you can put static pages in the views directory. Your controller will load them as if they were view files - inside a CI context - without re-writing them or specifically coding a controller for each page. Migrate your existing site in one fell swoop. Then you can piece out the functionality by adding controller methods so that it progressively gets more CI-like.

You “drop in” a fully functional static (or dynamic) existing website into the views directory of a new CI install and have it work inside a CI context (controllers, models, and views, etc…). When you are ready to start adding dynamic stuff/overriding the static pages, you just add methods to the child controller. The methods take precedence over the auto-loading of static view files.

For each view file you want to stop auto-loading, just write a controller method that has the same name - it will take precedence. It's that simple.

This is a parent/child controller combination to help you migrate html/php sites. It supports nested views and (when enabled in CI config.php file) even GET queries.

Base controller - the parent class

<?php
// DESCRIPTION: 
// use _remap() method to call up view files
// via uri if they exist in a subdir of views dir
// but only if there is no method in the controller
// this allows "overriding" default view files
// just by adding methods to this class
// or to the child classes

// you can drop an entire existing website in views/site_migrate
// and the files will be served through the CI view mechanism

// OPTIONAL: support for GET queries
// you need to change these config items to 
// allow GET query strings to reach your files
// added =&? to support queries in the URI
// $config['permitted_uri_chars'] = '=&?a-z 0-9~%.:_\-';
// must enable query strings
// $config['enable_query_strings'] = TRUE;
// may have to change the uri_protocol (see config.php for options)
// $config['uri_protocol']    = 'REQUEST_URI';

class Site_migrate_base extends CI_Controller {

    var $default_view_and_method = 'index';
    
    function Site_migrate_base()
    {
        parent::__construct();
    }
    
    function _remap()
    {
        $view_or_method = $this->uri->rsegment(2,$this->default_view_and_method);
        
        // if the method exists in any parent/child class, run it
        // else load the view file &#40;even nested views by uri string&#41;
        if (method_exists($this,$view_or_method))
        {
            $this->$view_or_method();
        }
        else
        {
            // the ruri string has a trailing slash we don't need
            $local_view_path = rtrim($this->uri->ruri_string(),'/');
            // if there is a question mark, pull out the filename for passing to view
            $view_file = strtok($local_view_path, '?');
            // append the default_view string if ruri targets a directory
            $server_path_to_view = APPPATH.'views/';
            $view_file = (is_dir($server_path_to_view.$view_file)) ? $view_file.'/'.$this->default_view_and_method : $view_file;
            // MODIFIED: 20110627 
            // you must make a change in your migrating code - the old 
            // site must be modified if site_migrate is to support it - 
            // it must think it is still the front most file being 
            // served by apache in its own document root...
            // only now, the document root will be the site_migrate directory
            // where you just dumped the old site to be migrated
            // pass the docroot variable to the "view" file so that it can be used
            // in scripts that need the absolute path to the view file 
            // this lets us refer to the new "docroot" in any scripts
            // most basic migrating sites won't need this, but...
            // use it in any files in the old site that need to believe they are at document root:
            // chdir($site_migrate_docroot);
            // make sure you put it before ANY require()s, or include()s for files 
            // in the relative path
            $site_migrate_docroot = dirname($server_path_to_view.$view_file);
            $this->load->view($view_file, compact('site_migrate_docroot'));
        }
    }
    
    // this is a demo function
    function test_method_in_parent($in)
    {
        echo $in . ' uri sent into class: ' . __CLASS__;
    }
}

/* End of file site_migrate_base.php */
/* Location: ./system/application/controllers/site_migrate_base.php */

extended controller - the child class

<?php

require_once('Site_migrate_base.php');

class Site_migrate extends Site_migrate_base {

    function Site_migrate()
    {
        parent::Site_migrate_base();
    }
    
    function test_method_in_child($in)
    {
        echo $in . ' uri sent into class: ' . __CLASS__;
    }
    
}

/* End of file site_migrate.php */
/* Location: ./system/application/controllers/site_migrate.php */

Routes: This is not required, but if you want to remove the site_migrate string from the URI, you can use routes. You can use the following "catchall" route to send all URIs to the site_migrate controller. Other routing techniques are discussed in the forum thread attached to this wiki page.

NOTE: if you use this "catchall" route, be careful because it routes EVERYTHING into the site_migrate controller! see this thread where a chdir error was being thrown when the dev using site_migrate made a separate, new controller outside of site_migrate but forgot about the catchall.

$route['(:any)'] = 'site_migrate/$1';
Clone this wiki locally