Remote Config Files In CodeIgniter

I ran into a situation recently where I had multiple CodeIgniter apps which depended on the same config values. No problem, right? Just use a common third_party folder. That would work, except they were on different servers! My solution was to echo the config as JSON in one place, grab the JSON in other apps and load them as config values. Now you can do the same!

Setup

  1. Install sparks at GetSparks.org
  2. Install the curl_load spark

Usage

First, do this in your config file:

<?php // DON'T put the usual !defined(BASEPATH) part up here
 
$config['this_key'] = 'value';
$config['that_key'] = 'value';
 
// if it's not loaded by CodeIgniter, echo it as JSON so
// we can grab the keys/values remotely
if (!defined(BASEPATH)) echo json_encode($config);

Now in your controller, use the curl_load spark to load the config file:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 
class test_controller extends CI_Controller
{
    public function index()
    {
        // replace x.x.x with version number
        $this->load->spark('curl_load/x.x.x');
 
        $this->curl_load->load_config('http://example.com/path/to/config.php');
    }
}

If you need to secure the values of the config file, you can add optional http authentication credentials:

$this->curl_load->load_config('http://example.com/path/to/config.php', 'http_auth_username', 'http_auth_password');

Or you could load an array of config files:

$this->curl_load->load_config(
    array(
        array(
            'url' => 'http://url1.com/config.php'
        ),
        array(
            'url' => 'http://url2.com/config.php',
            'username' => 'optional_http_auth_username',
            'password' => 'optional_http_auth_password'
        )
    )
);

Last but not least: You can set it to autoload config files in

config/curl_load.php
. Just add your config files in the same array format as above:

$config['curl_autoload'] = array(
    array(
        'url' => 'http://url1.com/config.php'
    ),
    array(
        'url' => 'http://url2.com/config.php',
        'username' => 'optional_http_auth_username',
        'password' => 'optional_http_auth_password'
    )
);

This is really cool, especially when you autoload the spark as well. Then your config values will automatically be loaded without you having to do anything!

$autoload['sparks'] = array('curl_load/x.x.x');

If this helps you, leave me a comment. Have fun!

Query Strings in CodeIgniter

CodeIgniter really does not like query strings. It's just downright mean.

  1. $this->uri->uri_string() removes the query string. Why?
  2. current_url() from the url helper removes the query string. Why?
  3. You can use query strings instead of segment-based urls such as http://example.com?c=controller_name&m=method_name instead of http://example.com/controller_name/method_namebut they have a nasty warning:

If you are using query strings you will have to build your own URLs, rather than utilizing the URL helpers (and other helpers that generate URLs, like some of the form helpers) as these are designed to work with segment based URLs.

Not a good deal! Plus there are no built-in helpers or libraries to grab the query string and do stuff with it.

But why use query strings at all? I thought segments were better?

  1. Unlike URI segments, query string segments are all optional. If you have 5 key/value pairs, you can include just items 1 and 5 if you want.
  2. Unlike URI segments, query string segments can be put in any order. If you have the same 5 items you can order them like 4,5,3,1,2 if you want.

These are big deals, because they are a giant pain in the ass with segments. For instance, let's say you have 5 segments and you just want to change segment 5 from the default. You have to send the default values for segments 1-4 first! So your url ends up looking something like this:

http://example.com/1/true/false/0/fifth_segment 

Looking at that url it makes no sense. You don't know what 1, true, false, or 0 refer to. But you are forced to type them all. What happens if one of these default values change? Or if the order changes? Or if you have to add or remove a segment? You have to change all your URLs! What a pain in the ass!!

Now segment-based urls are fine for hierarchical websites such as /products/outdoor/chainsaws/12. But for web applications, they totally suck. The way I see it there are two possible ways to fix this in CodeIgniter. You can either extend the URI and URL classes or write a new helper/library. I chose not to mess with URLs and just create a helper so I could use it in a view by just calling a function without $this->helper_name-> in front. So here's my query_string_helper:

Query String Helper
Download

It has just two functions:

  1. query_string($add, $remove, $include_current)This just echoes the query string with no params.
    1. Param 1 allows you to add an array of items to the query string.
    2. Param 2 you can either send a string of a key you want to remove or send an array of keys you want to remove.
    3. Param 3 lets you ditch the current query string if you want and just make a new one.
  2. uri_query_string( same params as above ) This includes the full current uri with the query string on the end. It allows you to manipulate the query string in the same ways as above.

Now you can just replace all your $this->uri->uri_string() or current_url() calls with uri_query_string() and you're good to go!

Getting CIUnit to work with Sparks

I recently got bit by the Sparks bug again. If you don't know, Sparks is like CodeIgniter's version of Ruby Gems. It's a command-line-based package manager that lets you install stuff for CodeIgniter quickly and keep it up-to-date. It's a great idea and I want to port my libraries over to this system.

So I thought I'd try to get Kenji's CIUnit working with Sparks. His wiki says to just change one line in MY_Loader.php (which is created by Sparks) and you're good to go. I found this to not be the case, so I did a little digging. Here's what you need to do to get them to play nice together:

If you haven't already, start by installing Sparks.

In application/core/MY_Loader.php change this:

define('SPARKPATH', 'sparks/');

to this:

define('SPARKPATH', APPPATH . '../sparks/');

Then in application/third_party/CIUnit/core/CIU_Loader.php change this:

class CIU_Loader extends CI_Loader {

to this:

class CIU_Loader extends MY_Loader {

Then you should be good to go. CD back to your root/tests in the terminal and hit phpunit. If you've loaded sparks, they should now work without erroring out. Huzzah!

New open source CodeIgniter projects

I've made some open source projects available on GitHub:

CI Alerts - A CodeIgniter package to save and display different types of alerts. It wraps alerts with html based on the type of alert.

CI Authentication - A CodeIgniter authentication package for complete authentication management.

Carabiner - a fork of Tony Dewan's Carabiner library. This version also accepts and compiles .less files.

Base CodeIgniter App - a preconfigured codeigniter app with some useful submodules such as carabiner, authentication, twitter bootstrap, and PHPUnit.

Bookymark - a sample CodeIgniter app using all of the above libraries, general CodeIgniter best practices, and fully unit tested. Example app is live on bookymark.com.

I hope this will help you develop CodeIgniter apps more easily!