Composer with CodeIgniter

Posted: 2012-05-07
Category: PHP

Composer is the best thing for PHP since sliced arrays and using it in your applications means you have easy access to a large selection of well written PHP packages that plug and play with any framework that supports PSR-0 namespacing. This is BRILLIANT as it means less reliablity on the framework and framework-specific code, and helps you get towards the goal of portable code where the framework is essentially just the wrapper. FuelPHP 1.x works with an optional autoloader and 2.0 will support Composer packages out of the box as does Symfony2 and I hear Drupal are working it in too. This interoperability is brilliant, but how do you use it with CodeIgniter?

People have suggested that CodeIgniter 3.0 should be rewritten entirely around Composer and we make it PHP 5.3 only, but rewriting is a silly suggestion and PHP 5.3 still only has about 30% coverage on servers so that is not going to happen. Besides if CodeIgniter 3.0 became PHP 5.3 over night then either it would break everyones application because it changed so much, or change so little that it would not merit a PHP version bump.

That said, if you want to start using Composer components in your application there is no reason why you should not. The code is mainly PHP 5.3 but by slowing moving the majority of your application from framework specific code to generic packages that work in any framework you free yourself from being limited to a specific framework and will find a transition to FuelPHP 2.0, Laravel or Symfony2 much easier in the future.

Sadly Laravel have not announced any plans to exclusively support Composer out of the box, but it is just as easy to work with Composer in Laravel as it is in CodeIgniter, so let's get going:

Step 1

Navigate to your project and install composer:

$ cd /path/to/my/project
$ curl -s http://getcomposer.org/installer | php

You could instead use Homebrew to install composer system-wide, which is my preference:

__Update: __ It turns out the homebrew package is pretty old. I installed a few weeks previous to this post, but users are having problems. Use the .phar method for now.

$ brew install composer

Step 2

Next you need to make a composer.json in the root of your project (not the application folder):

{
    "require": {
        "kriswallsmith/buzz": "*"
    }
}

This will add a requirement for the Buzz package, which is a handy HTTP Request / Response PHP 5.3.x class.

Step 3

To actually install these files to your CodeIgniter project you simply run the install command:

$ composer.phar install

If you have installed via Homebrew then this will be:

$ composer install

Then you should notice composer creating a ./vendors folder in your application and code will be installed there.

Step 4

To autoload this newly installed code all you need to do is drop a single line of PHP into your index.php

include_once './vendor/autoload.php';

Done

It is as simple as that. Now in my test controller I can use Buzz happily, along with any other PSR-0 code that I install via Composer:

class Test extends CI_Controller
{
    public function index()
    {
        $browser = new Buzz\Browser();
        $response = $browser->get('http://www.google.com');

        echo $browser->getLastRequest()."\n";
        echo $response;
    }
}

To see what is available check out Packagist - the default repo for Composer packages.

If you are not familiar with Composer or PSR-0 support then you should really look into it. The PHP Standards group or PHP-FIG are doing a brilliant job of taming the mess that is third-party PHP code and are building some great standards, which are open to discussion and voted on by some of the best PHP developers around.

Get involved and help PSR-1 and PSR-2 become something brilliant. In the mean-time enjoy all the PSR-0 code and use it wherever the hell you develop.

Stop making CodeIgniter libraries, Laravel bundles and Zend modules, make Composer packages.

Comments

Gravatar
Marco Monteiro

2012-05-07

This is brilliant.

And I completely agree with you, we should start all doing composers instead of libraries.

Anyways, good tutorial. Specially for me (since I never actually used composer packages).

Thanks.

Gravatar
Joost Van Veen

2012-05-08

Great stuff, and well explained. Good hope PSR-0 could finally headstart us into building libs that can be easily shared and used in any PHP environment.

Gravatar
Mike Funk

2012-05-08

I was not able to clone composer in homebrew. It says "no available formula for composer." I did brew update first and still nothing.

Gravatar
Jordi Boggiano

2012-05-09

A few corrections/notes:

- Composer can now autoload more than PSR-0 stuff, is supports classmap for other projects, and also include_path for legacy projects. See http://getcomposer.org/doc/04-schema.md#autoload

- Please update the post to contain: include_once './vendor/autoload.php'; - the .composer dir has been deprecated. See https://groups.google.com/d/msg/composer-dev/fWIs3KocwoA/nU3aLko9LhQJ

- The homebrew package is very old AFAIK, it will be included in homebrew-php soonish once we release a new version (but I'm waiting on some blocking critical fixes for this).

Gravatar

2012-05-09

Thanks for the heads up Jordi, I've added a note about Homebrew and updated the include path. I've also joined the group so I'll hear about those sort of updates quicker.

As for the classmap stuff I was aware Composer could load non-PSR-0 packages but I did not want to get into a "this is how you use Composer to install whatever the hell else" sort of conversation. Thanks for adding the note, I might write a "Use Composer to Auto-load your Models/Libraries/Sparks" or whatever.

Gravatar
Rogerio Prado De Jesus

2012-05-21

Hello, Phil.

What is your opinion about Sparks now?

Do you think people should stop making them too?

I'm asking that because there is a working in progress to make sparks be part of CodeIgniter core, isn't?

Gravatar

2012-05-21

Sparks are as much of a good idea as they always have been: CodeIgniter needs re-usable code too - but the way they are implemented is going to change a little bit.

getsparks.org will become a Composer repo - just like Packagist is - so that we can move all Sparks (which are VERY CodeIgniter specific) to that repo. Then, this autoload logic is implemented so that normal Packagist packages can be installed as well as Sparks, all through the Composer command line utility.

This means CI doesn't need a specific command line tool and we're following some standards.

Obviously most Composer packages are PSR-0 so require PHP 5.3, but Composer does not enforce PHP 5.3 usage and can just be used as a delivery channel, so but combining Sparks and Composer we should see optional functionality for 5.3 users and the same current Sparks functionality for 5.2 users.

Gravatar
Rogerio Prado De Jesus

2012-05-21

Oh, that's awesome, Phil.

I'd like to be more envolved with this, maybe joining some google group or similar (I mean about Sparks migrating to Composer way).

Could you list some of these groups for us?

Gravatar
Facemaskman

2012-05-30

Thanks for your introduce.
It's helps me understand the hold picture.

Gravatar
Victor Schelin

2012-07-11

Hi Phil,

after I've installed Composer and added the line to load the composer autoloader to my index.php, my custom autoloding of core/ files stopped working. I have a "Backend_Controller" in core/ and to load that I've added the autoloader function from your "Keeping it dry" post into my config.php.

The error I'm getting is that the class does not exist (Backend_Controller that is). It seems that when loading Composer, the autoloader function stopped working.

The only way I got it all to work was to create a pre_controller hook and from there load composer instead from my index.php.

Any thoughts on how to solve this easier than a hook?

Regards,
Victor

Gravatar

2012-07-11

Victor: Yeah that will happen because __autoload() is very old, and is overridden by SPL Autoload methods. Instead, do this:

"autoload": {
"classmap": ["application/core"]
}

Gravatar
Victor Schelin

2012-07-16

Thanks Phil, worked great!

Gravatar
Adam Jackett

2012-08-08

I was talking to Taylor yesterday, it turns out Laravel 4 is going to be heavily integrated with Composer. Also, the Eloquent ORM is going to be a Composer package very soon, which is great news for me at least. I really want Eloquent in CodeIgniter. The only downside is that obviously this still requires php 5.3, and not all of my clients' servers are running 5.3 yet.

Gravatar
Gregor Mckelvie

2012-08-21

Hi Phil - thanks for the post. Is there any adverse affect by installing composer when the application folder is stored above root? My application directory with composer installed is:

* application
* public_html
* system
* vendor

Does vendor need to be within application? I'm getting "PHP Fatal error: Class 'Buzz\Browser' not found in..." using your example above.

Sorry if this is noob question (!)

Gregor

Gravatar
Ian

2012-08-21

Good info here. I tried figuring this out a few days ago after learning about composer at tutsplus.com .

I wish I'd found this article before the headache :-)

I used it to integrate php-activerecord without using sparks.

My solution which is working so far with HMVC was to install composer in "Third Party" directory and then add a My_Controller.php which requires phpar in the constructor and then setup the ar config so it's available in controllers when I load a model.

It's definitely easier to just require it in index.php like you said.

Gravatar
Tjorriemorrie

2012-12-06

I agree, it doesn't work the way you described. How can I use a package in my controller? Do I need to namespace the whole application? That might not work as I'll need to add a backslash to each DateTime..., etc. I just want to use one namespaced vendor package in one controller :(

Gravatar
Tárcio Zemel

2012-12-25

For those who are not getting the results shown in the tutorial, you must call the Composer autoload BEFORE the CodeIgniter bootstrap: http://pastebin.com/6ffYwdkf

Posting comments after three months has been disabled.