A First Look at Fuel

UPDATE: I didn’t really mention that Fuel is an open source project. If you want to help out, head over to their github page, fork your own repo and get submitting!

UPDATE UPDATE: I’m not actually affiliated with the Fuel project, just a user. Please direct all suggestions over to their contact form or comment on github. thanks :)

There was an announcement a while back from Phil Sturgeon and a few others (shortly after some issues came to light with a certain other framework) about a new framework they were developing that came to be called Fuel. According to their site, the goal is to be:

a simple, flexible, community driven PHP5 framework. FUEL aims to take the best idea’s from a bunch of frameworks, throw away the “not so good” stuff, and create one awesome framework. It is provided under the terms of an MIT License, which means it’s free to use in your personal, commercial or enterprise projects.

What’s that? Why does the web need another framework? Well, to be honest, it doesn’t – but there is one thing that Fuel has going for it. If you’re one of the many CodeIgniter users out there, you’ll feel almost immediately comfortable with it. Since the devs are CodeIgniter fans themselves, they’ve built a lot of the same feel into how Fuel handles your applications. Unfortunately, there’s not a user guide for it yet, so I figured I’d share some of my experiences with it and maybe get you set down the road to fuel-ing your app (yep, that cheesy pun was required).

So, to get started, here’s some simple installation instructions:

  • Grab the latest source from Github (this will probably change when they make releases)
  • Unpack the files into a web-accessible directory. Mine are in /www/htdocs/fuelapp
  • There’s a /public directory in there – that’s where you need to point the DocumentRoot to
  • Make sure that AllowOverrides is set to use .htaccess and that mod_rewrite is installed and working
  • Move the “example.htaccess” file over to just “.htaccess” to make the rewrites work
  • At this point, when you visit the host for your site, you should get the “Welcome” message
  • Be sure to chmod the app/cache and app/logs directories so that the web server user can read/write to the directories.

That should get you started and have your basic application structure all set to go. In the basic layout, your application will live in the /app directory (makes sense, eh?) with the actual framework living in /core. As far as the three pillars of a MVC framework – they’re in classes/controller, classes/model and views. There’s also a config directory that houses the configuration files for your application.

Let’s start with the controllers – here’s an example snippet from the welcome controller showing you a basic controller structure:

[php]
<?php

use FuelController;

class Controller_Welcome extends ControllerBase {
public function action_hello()
{
$this->output = ‘Hello ‘.$this->param(‘name’);
}
}
[/php]

This action is called at http://localhost/welcome/hello (obviously replacing the hostname with yours).

If you haven’t seen something like the “use” call before, don’t worry. It’s just namespacing. The framework is PHP 5.3 only, so they can use fun things like namespacing and closures. In the example above, they load the FuelController namespace and extend the ControllerBase by default. There’s some naming conventions to look out for in controllers:

  • Controller class names should be “Controller_*”
  • They should extend ControllerBase
  • Methods should be “action_*”
  • Output pushed to the view belongs in $this->output

Something you don’t see in the above example is how to interact with the view. You’ll need to use the View class to get your data loaded into the right place. Here’s an example of that:

[php]
public function action_index()
{

$arr = array(
‘data’ => ‘test data’,
‘partial’ => View::factory(‘test/partial’)->render()
);

$this->output = View::factory(‘test/index’,$arr);

}
[/php]

If you’re quick, you’ve spotted the “partial view” I’ve simulated. By calling that “render” method on the view object, it returns the results as a string that can be appended. The parameter in that “factory” call is the path to the view file. So, the string “test/index” refers to the file /app/views/test/index.php.

There’s already some handy built-in helpers for the framework. It seems like all of them I saw were able to be called statically. So, for example – here’s how you could use the Uri helper:

[php]
public function action_uri()
{
$detect = Uri::detect();
var_dump($detect);
}
[/php]

Oh, and one last thing I know some of you are wondering about – database connectivity. Right now, there’s only MySQL connectivity, but I’m sure that’ll change quickly. Here’s a simple database example to get you started:

[php]
public function action_database()
{

$db = Database::instance();
$tables = $db->list_tables();
var_dump($tables); echo ‘<br/><br/>';

$result = $db->query(Database::SELECT,’select * from test_data’,false);
var_dump($result); echo ‘<br/><br/>';

var_dump($result->current());
$result->next();
var_dump($result->current());

$this->output = ‘test';
}
[/php]

Instead of just returning arrays or whatever, the datbase calls by default return iterators. I nice touch in my opinion that could go a long way to help SPL adoption. You can also define an object type on the “query” call that lets you map to and object type.

So far so good…like I said, if you’re a CodeIgniter fan, you’d do well to check out Fuel. It feels more like what CodeIgniter should be when it grows up and joins the rest of the PHP frameworks in the PHP5+ world. I’ve already submitted a small update back to the framework and can already say that the community for it is friendly and open to whatever help they can get. Dan Horrigan, Phil Sturgeon and Jelmer Schreuder are doing a great job so far and I look forward to some more great things to come.

I’m going to continue messing with it and will try to post any fun things I might come across. Feel free to ask me about installation or some of the basics of the framework. I’m happy to share what I know.

Oh, and for those wondering, here’s my sample controller I’ve pulled these samples from:

[php]
<?php

use FuelController;

class Controller_Test extends ControllerBase
{

public function action_index()
{

$arr = array(
‘data’ => ‘test data’,
‘partial’ => View::factory(‘test/partial’)->render()
);

$this->output = View::factory(‘test/index’,$arr);

}

public function action_caching()
{
Cache::set(‘mykey’,’testing’);
$cacheOutput = Cache::get(‘mykey’);

$this->output = ‘cache output: ‘.$cacheOutput;
Cache::delete(‘mykey’);

$this->output.=’cache after: ‘.Cache::get(‘mykey’);
}

public function action_uri()
{
$detect = Uri::detect();
var_dump($detect);
}

public function action_database()
{

$db = Database::instance();
$tables = $db->list_tables();
var_dump($tables); echo ‘<br/><br/>';

$result = $db->query(Database::SELECT,’select * from test_data’,false);
var_dump($result); echo ‘<br/><br/>';

var_dump($result->current());
$result->next();
var_dump($result->current());

$this->output = ‘test';
}

}

?>
[/php]

12 comments

  1. It looks more like Kohana than CodeIgniter, but as stated on their website take ‘the best idea’s from a bunch of frameworks, throw away the “not so good” stuff’.

    There is a discussion whether Kohana 3.x should use 5.3 features, too. So Kohana can take the best idea for that during the exchange between these two framework.

  2. After first look on this code, I think it looks like ZF. It’s nothing new there, only different class names and php 5.3 features (namespaces). I want give it a try definitely. All in all – boring.

  3. I have to confess – it looks interesting but:
    1. Why didn’t you stick to the Zend/PEAR coding standards? Food for thought: http://groups.google.com/group/php-standards/
    2. Why Controller_Test instead of TestController?
    3. Why action_index instead of just index? If need to have a method that is not callable outside the class – make it protected. No need to add complexity where it’s not needed.

    My advice is to refactor the framework to comply with the PEAR/Zend coding standards before you have to worry about BC Breaks and while the codebase is relatively small.

    If you need help – contact me. I’d love to help with some coding.

  4. @dyron, @sokzzuka yep, I do agree it has some similarities to the Zend Framework and Kohana stuff (in fact, I think there’s even references to Kohana in the source). I just found it familiar given my work with CodeIgniter.

    @vladislav http://fuelphp.com/contact would love to hear your suggestions :)

  5. @Vladislav Veselinov:

    I can only speak as a Kohana user, since the CFS is used by Fuel, too.

    2. Because of the cascading file structure. AFAIR you can also create ‘app/classes/test/controller.php’ to name your class ‘Test_Controller’. It’s a convention that underscores are replaced by directory seperatores. ‘Controller_*’ groups your controller in one folder even a convention too. ‘app/classes/TestController.php’ and ‘class TestController’ is possible too. Then all controller, model, etc files residing in the same directory and aren’t

    3. What if you want a private, not accessible controller method? Sure you can use ‘private function test()’, as you stated. But i think it’s the same like SQL injection. You have to force someone to use it the right way. Earlier SQL looks like “SELECT * FROM table WHERE col = ‘$val'”. Only a few stated that $val have to be escaped and so noone did. Making controller methods dependent on mehtod visibility, most of unexperienced devs think ‘public function calculate()’ is enough because it works, finding out that you can access it via url, that wasn’t intend to.

  6. A view factory? In my homemade MVC system this is all done automatically.
    public function index()
    {
    $this->bag[‘data’]=’test data';
    }
    Saw Fuel has similar approach to queries as my framework does but Fuel only handles pure SQL.
    public function database()
    {
    $result = Query::create(‘test_data’)->execute();
    var_dump($result); echo ”;
    $result = Query::create(‘test_data’)->where(R::Eq(‘active’,1)->And_(R::Like(‘Name’,’Johns’)->execute();
    var_dump($result); echo ”;
    $this->RenderText(‘test)';
    // or RenderToAction(‘action on this ctrlr’), Render(ctrl,action), RenderFile(filepath);
    }

    Fuel don’t seem to support ActiveRecord yet though.

  7. Thanks for the write-up on this! FUEL is getting a lot of attention right now and we really think it has a place in a world already very full of frameworks.

    We have simplified a few things since this article (or since you grabbed your copy at least Chris).

    1. DB now uses the Kohana DB library.

    Imitation is the sincerest form of flattery, and much like the Cascading File System Kohana’s DB class is brilliant. We are still building on top of it but it is easier than the example you have posted. You can look in the Migrations library to see the difference.

    2. Controller Declarations are more “use”less

    Terrible pun aside, we have removed the use Fuel/Controller to simplify the creation of the controller. Instead you now can start a controller with just this:

    class Controller_Welcome extends FuelControllerBase {

    See the welcome file here:

    https://github.com/fuel/fuel/blob/c7e1af64aaf60fc4a4a0d8e8d40f7954c3514797/fuel/app/classes/controller/welcome.php

    So, to answer a few questions:

    “Why didn’t you stick to the Zend/PEAR coding standards?”

    We don’t like the Zend/PEAR coding standards. Myself, Dan and Jelmer all come from a mainly CodeIgniter background and we use Allman with the EllisLab guidelines. They are short, concise and cover everything in a good standard.

    “Controller_Test instead of TestController”

    dyron covers this perfect. _ is replaced with / to create a VERY flexible system of autoloading classes. Controllers and Models are just another type of class, so they are treated the same. Controller_Foo is translated directly to app/classes/controller/foo.php. If we have Controller_Foo_Bar it goes through to app/classes/controller/foo/bar.php. Just like that we have unlimited sub-domain support and we dont get any name clashes with other classes. For example I could have Controller_Admin_Users and it wouldn’t clash with Model_Users or even a Users class/library in app/classes/user.php.

    It looks a little odd, but there is method to the “madness” in this case.

    “Fuel don’t seem to support ActiveRecord yet though.”

    Give us a chance! We are very new and the mention in my article gave Fuel more publicity than we expected at this point. Now we have the Kohana DB class as a base Dan will be working on a simple Query Builder to sit over the top, then a full ORM hopefully fairly similar to the Rails ORM as its the most logical of the lot.

    The most likely candidate is http://lukebaker.org/projects/activerecord-in-php/ but it will need some work to get it up to scratch. The last update was 2008 :)

    There is work to be done, but FUEL has a lot of potential. The documentation will be a priority once the first alpha is released.

  8. Hello,
    Thanks a lot for your posts.
    I’m still learning PHP and CodeIgniter is too friendly to me for my small apps.
    I was just watching fuel of Github.
    Your post lead me to give a test drive.
    I hope you’ll write more posts soon.
    It’ll be really nice to grow with the birth of the best PHP5+ framework on the planet(Hope so).
    :D

  9. I don’t agree with the idea that the public dir should be inside the code dir. Instead, I think that the code should be in a subdirectory of the public dir (protected from reading via http of course.) This way you don’t have to mess around with document root and it gives the JS/CSS people easier access to their files.

    The only “developer” files in my app root are .htaccess to handle url rewriting and index.php which has to be accessible via http for the rewriting to work.

  10. Pies: This is something that nobody will ever agree on. We’re following the approach that if people dont like it, they can move it. You can just drag the fuel folder into your public, or rename the public folder.

    What I have done on my server is git clone in the vhost root then created a symlink from public_html to public, meaning i can git pull all updates without ever needing to mess with Apache. But that is purely because I am lazy :)

  11. It’s just that what PHP lacks is standards. There is a movement trying to create standards but the community is not supporting it and that’s definitely not a step forward. I get that you come from a CI background(not my thing but that’s not really the point), but with a new project you are free to change things – to correct your previous mistakes(in my opinion, the CI naming convention is one if its most serious drawbacks). It’s the framework developers who can help promoting standards. Now, imagine a developer who wants to use Fuel together with Doctrine(or any PEAR-compliant library).

    do_something();
    …..
    $userRecord = new User();
    $userRecord->setName(‘John’);
    $this->em->persist($userRecord);
    …..
    $something_fuel_related->do_something();
    $something_fuel_related->do_something_else();
    }
    ….

    Another thing is that having namespaces mixed with Bla_BlaBla naming is just … ugly!

    It’s your framework and you are free to do whatever you want with it. It doesn’t matter whether I approve it or not. I just wanted to share my opinion. Good luck with the project!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>