Skip to main content

Flying with Phalcon PHP Framework

Oct 12 '15

phalcon php framework

After a bit of research on memory footprints of php frameworks, I saw a fabulous performer, Phalcon, coming in at 1/5th the usage of Laravel 5 (http://blog.a-way-out.net/blog/2015/03/27/php-framework-benchmark/). This led me to tinkering about, and it brought me some mixed emotions.

Initially, the setup of Phalcon was a bit more involved than most, but this is understandable because you’re now using a compiled php extension instead of a code library to work with. With some trial and error, I was able to build out pretty simple vagrant for playing around (https://github.com/bmoore/phalcon-vagrant – feel free to give it a shot). With the first look at the framework, Phalcon does not have much opinion about the structure of a site, which is a double-edged sword. You are free to approach your web application in any direction, but you are going to spend some time configuring your file structure. If you want to speed past that, with some opinion, the phalcon devtool can speed things up. I’ve used the devtool in the vagrant just to jump into development.

If you’re familiar with Laravel, CodeIgnitor, or  other MVCs, you will quickly understand the structure of the app directory. You will see your standard models, views, and controllers directories. Default phalcon routing has the path logic of /:controller/:action/(:params/)+with the IndexController/IndexAction being set for /. You will need to alter the configs to add custom routes. The simplest way is in app/config/services.php importing the Router class and setting the router with custom routes added.

use Phalcon\Mvc\Router;/**
 * Setting routes
 */
$di->set('router', function() {
    $router = new Router();
 
    $router->add('/{user}', array(
        'controller' => 'user',
        'action' => 'profile',
    ));
 
    $router->add('/login', array(
        'controller' => 'user',
        'action' => 'login'
    ));
 
    return $router;
});

Phalcon devtools will also let you handle some simple scaffolding to help build out models and stub controllers. `phalcon scaffold user` will actually read the user table from the database, and structure the model after it, as well as create a controller and stub out CRUD functionality, as well as simple view templates for the generated actions.

The createAction of the user controller:

/**
 * Creates a new user
 */
public function createAction()
{
 
    if (!$this->request->isPost()) {
        return $this->dispatcher->forward(array(
            "controller" => "user",
            "action" => "index"
        ));
    }
 
    $user = new User();
 
    $user->name = $this->request->getPost("name");
    $user->mail = $this->request->getPost("mail");
 
 
    if (!$user->save()) {
        foreach ($user->getMessages() as $message) {
            $this->flash->error($message);
        }
 
        return $this->dispatcher->forward(array(
            "controller" => "user",
            "action" => "new"
        ));
    }
 
    $this->flash->success("user was created successfully");
 
    return $this->dispatcher->forward(array(
        "controller" => "user",
        "action" => "index"
    ));
 
}

Phalcon views can be handled in multiple ways. You are free to use simple php templates, but you are also able to take advantage of a Jinja styled template language they call Volt (https://docs.phalconphp.com/en/latest/reference/volt.html). I prefer this style, because it leaves templates cleaner, and limits the amount of logic you can perform inside the templates, forcing a clean approach for view templates. My one gripe about the view functionality is that it predetermines the layout based on the controller name, which seems to require the template called to declare which layout it is going to use. But as you can see, the volt templating language can be pretty clean looking, like this login form page:

{% extends "layouts/page.volt" %}
 
{% block body %}
<h2>Login</h2>
<div class="login">
  <form method="post">
    {% for element in form %}
      <div class="messages">
        {% for message in form.getMessagesFor(element.getName()) %}
            <p>{{ message }}</p>
        {% endfor %}
      </div>
      <div class="input">
        <label for="{{ element.getName() }}">{{ element.getLabel() }}</label>
        {{ element }}
      </div>
    {% endfor %}
  </form>
</div>
{% endblock %}

All in all, I’m impressed with the Phalcon PHP framework. It is much more mature these days, and fully featured with libraries and helpers you would expect from a modern MVC for web applications. Just take a look at the available classes (https://docs.phalconphp.com/en/latest/api/index.html). I’ve yet to profile an app to see how it compares between Laravel and Phalcon, but just from the way it runs on a vagrant, I have a suspicion the benchmarks are going to be excellent.