How To Build Web Applications with HMVC PHP5 Framework Kohana

Introduction

We started out our series with talking about Kohana and its installation process. Since the framework does not require any additional configurations or modifications, we are ready to begin with learning web-application development basics using the Kohana framework.

In this DigitalOcean article, we will be jumping in on understanding how Kohana is designed to work along with its most important parts. We will go over the HMVC (Hierarchical Model View Controller) pattern and learn how to create one of each – and get them to work together!

Note: This is the second article in our Kohana series, focused on working with the framework. To see the first concerning installing it, check out Getting Started with Kohana. To see about deploying a Kohana based web application, check out Deploying Kohana Based PHP Web-Applications.

Glossary

1. Convention over Configuration

2. Kohana’s Choices and Its Conventions

1. File Naming
2. Coding Style

3. Kohana and The MVC Pattern

4. Controllers – “C” of the MVC Pattern

1. Conventions
2. How does it work?

5. Actions

1. Conventions
2. How does it work?

6. Model – “M” of the MVC Pattern

1. Conventions
2. How does it work?

7. View – “V” of the MVC Pattern

1. Conventions
2. How does it work?

8. Routing

1. Conventions
2. How does it work?

9. Handling Errors with Kohana

1. Registering HTTP Error Page Controllers
2. Throwing HTTP Errors

10. Sessions and Cookies

1. Sessions
2. Cookies

Convention over Configuration

In application programming, Convention-over-Configuration (or coding-by-convention) is a term used to describe a certain type of design (i.e. application structuring / modelling) whereby applications trust that code being built respects the rules and core instructions (i.e. connecting Models with Controllers automatically – identifying using names).

This application development paradigm is used to reduce all sorts of confusing, overly complicated and unnecessary options (and needs) for classic, file based configurations (e.g. config.xml). It is based on components [forming the application] following the already established conventions to have things work smoothly – hence eliminating the need for additional configuration.

Kohana’s strict reliance on this concept makes it one of the easiest and simplest to work with frameworks. If you follow Kohana’s conventions (including – and very importantly – the coding style), everything will be easier to create and to maintain.

Kohana’s Choices and Its Conventions

File Naming

In order to facilitate PHP’S autoloading of required files (i.e. those created later), Kohana uses a strict style: first letter of class names are capitalised and underscores are used to separate each word forming it – as per PSR-0 Autoloading Standard.

Example:

#  Class Name             -     Class File Location
1. MyClass                      classes/MyClass.php
2. Controller_ClassOne          classes/MyWork/ClassOne.php
2. Controller_ClassTwo          classes/MyWork/ClassTwo.php

Note: Remember that by the convention, all class defining files must exist under the classes directory.

Coding Style

Albeit not strictly necessary, for the above mentioned reasons, Kohana recommends sticking with the BSD/Allman style when it comes to writing your code.

This process consists of having curly-brackets on their own line.

Example:

// for (int i=0; i<x; i++)
if (a == b)
{
    proc1();
}

finally();

Note: Curly brackets following the class name are to be at the same level.

Example:

class MyClass {
// ...
// ..
/  .

Remember: To learn more about Kohana’s conventions, you may choose to refer to its documentation located here.

Kohana and The MVC Pattern

This section and the following related ones (Controllers, Actions, Models, Views) form the first major part of application development fundamentals with Kohana – creating procedures (functions) to process requests. The sections after this cover other key areas (e.g. defining routes, handling errors etc). You are advised to try these examples on your droplet as much as you like to get comfortable before moving on with building a production-ready application.

As we have discussed at length, Kohana uses the (H)MVC pattern to process requests. Applications developed using Kohana are better to follow this style as thoroughly as possible to create smoothly operating programs.

Controller – “C” of the MVC Pattern

Controllers are plain text files which constitute one of the major parts of processing an incoming request. It glues the rest of the pieces that form the MVC pattern and makes them all work jointly to create and return a response. Each incoming request, after being routed, gets passed to a matching controller and gets processed by calling an action (e.g. print_names).

Conventions

Kohana’s conventions also apply to its controllers and therefore, each controller must:

  • Exist under classes/Controller/*.
  • Have its name match the file name (i.e. Controller_Name inside classes/Controller/ as Name.php).
  • Follow the rest of the naming and styling conventions.
  • Extend the parent Controller class.

Examples:

# Each one of the below examples represent the top -
# section (definition) of a class on a single [class] file. 

# Example [1]
// classes/Controller/ClassOne.php
class Controller_ClassOne extends Controller {

# Example [2]
// classes/Controller/Namegroup/ClassOne.php
class Controller_Namegroup_ClassOne extends Controller {

# Example [3]
// classes/Controller/ClassTwo.php
class Controller_ClassTwo extends Controller_ClassOne {

How does it work?

Controllers work similarly to below:

  • Request – Controllers receive the request data wrapped as an object, attached to the [object] variable $this->request.
  • With Models – Controllers pass information to models to modify the database and data objects and they request/receive data from models to process the data (possible passing through views).
  • With Views – Controllers, after processing the information received with the request and data from models, pass this information by the view layer to return a final response along with its presentation (i.e. the view).
  • Response – Controllers return a final response wrapped as an object [variable] defined by $this->response (e.g. final view body can be set via $this->response->body($my_resp).)

Actions

Actions are [public] procedures (i.e. functions) defined under classes. They consist of callables for requests to be processed.

Conventions

By Kohana’s conventions, actions must have:

  • action_ prefix prepended to their names. (i.e. action_print_names).
  • public classification (i.e. public function action_print_names()).
  • $this->response->body($view) set at the end of their execution cycle to return a view to the user.

Note: There are two major exception to actions. These are:

  • before (public function before()) – Used to have code executed before everything.
  • after (public function after()) – Used to have code executed after everything.

Model – “M” of the MVC Pattern

Models in Kohana are plain text files containing classes or other data forming / containing objects which represent the layer right above the database (or any datasource). The distinct nature of these kind of objects (i.e. those used for representing actual data) make models perfect pieces of the MVC paradigm by allowing the separation of all procedures related to directly creating, modifying, updating or deleting data.

Conventions

By convention, classes defined under models – similarly to Controllers – must:

  • Exist under classes/Models/*.
  • Have its name match the file name (i.e. Model_Name inside classes/Model/ as Name.php).
  • Follow the rest of the naming and styling conventions.
  • Extend the parent Model class.

How does it work?

Usually models use an Object Relational Mapper (ORM) solution to expose data and ways to interact with it to controller classes. Kohana comes with its own ORM module that allows very well structured objects to be designed and created.

Upon receiving a command (possibly with further variables), model perform desired actions to either send back a response to request of data, or, update the database with what is given.

View – “V” of the MVC Pattern

View files form everything that is related to representation of final response. Of course, these files do not directly contain third party resources (e.g. images or other run-time dependencies); however, they form the base for what is to be provided to the end user. If you are designing a web-based API, views can be used to return desired data in a structured way that is easy to maintain. (e.g. json response to an ajax request).

When working with views, it is best to keep away all logical operations that would otherwise modify data-to-be-represented from view files. Views should be used (as much as possible) for forming the way the data is shown.

Conventions

  • View files must exist under views/ directory (e.g. views/login.php)
  • They should be as “dumb” as possible.
  • They should not be used for anything other than using the data provided to form a representation.

How does it work?

In order to form a final view, the controller passes a certain payload (data) to the view file(s) which process their way through them (e.g. iterate over a list to form a table’s columns). After compiling everything (template files with the payload / data processed), the view’s representation gets transferred by the controller as the final response to the request.

Routing

As we have diagramed and discussed on our first article in Kohana series, each request is parsed (processed) and routed. The way this works is set out mainly by how routes are defined in your application.

These elements form patterns which are matched against (in order they are written) requests to decide which action to call with the request payload.

Conventions

Unless you are strictly developing a module of its own, routes are usually defined under the bootstrap.php file – at the very end.

These routing mechanism definitions are extremely flexible and generous in the way they function – probably the most flexible in existence. You can use them to achieve great things very simply – just by following the correct schemas.

  • All route names must be unique.
  • They must be defined before the default route.
  • Must not contain special token parameters ((), <>).

Example:

# Route Syntax: set([name], [pattern])
# Pattern Syntax: (.. item ..)  <- optional elements,
                  <controller>  <- match a  controller,
                  <action>      <- match an action,
                  <id>          <- request variable

# Example [1]
Route::set('default', '(<controller>(/<action>(/<id>)))')
->defaults(array(
    'controller' => 'Welcome',
    'action'     => 'index',
)); 

# Route explained:
# By default, match all requests - optionally with:
#                                  /controller, and,
#                                - optionally with:
#                       /controller/action,     and,
#                /controller/action/id
# Use controller "Welcome" by default if none other matched,
# Use action "index" by default if one is not matched.

# Example [2]
Route::set('logops', '<action>',
array(
    'action' => '(login|logout)'
))
->defaults(array(
    'controller' => 'logops',
)); 

# Route explained:
# Match all incoming requests to /login and /logout with
# "logops" controller and call the related action (i.e. login or logout)

Note: As soon as a route is matched, the procedure stops. Therefore, all the additional routes (i.e. all bar the default route) must be created before the default one.

How does it work?

Request objects, upon being matched to a route, are transferred along with their data. This matching and request routing process consists of:

  • Match a request to a route
  • Find the relevant classes under classes/Controller directory.
  • Find the controller.
  • Find and call controller’s action callable.
  • Return the response (i.e. the view).

Handling Errors with Kohana

Together with unit testing, handling errors (in a sane way) is one of the most critical parts of almost any application. Kohana, using PHP’s ErrorException, turns errors into exceptions and allows their handling with its helpers.

Registering HTTP Error Page Controllers

A robust web application will handle errors well and offer results (i.e. a response) back to its user correctly. For this purpose, Kohana offers an exceptional error handling system (no pun intended – see above).

To register an HTTP error page to throw exceptions:

class HTTP_Exception_404 extends Kohana_HTTP_Exception_404 {

    public function get_response()
    {
        $response = Response::factory();
        $view     = View::factory('errors/404');

        $view->message = $this->getMessage();
        $response->body($view->render());

        return $response;
    }

}

Throwing HTTP Errors

Kohana has a very good and easy to operate error handling mechanism for throwing HTTP errors / exceptions.

Example:

# To create an error (exception) for 404 - Not Found Error
throw HTTP_Exception::factory(404, 'Not Found');

Sessions and Cookies

To facilitate working with sessions and cookies, Kohana provides helper classes which allow you to work with each securely.

Sessions

When working with sessions, you need to have a variable accessing the session instance.

# Accesing the session instance
$session = Session::instance();

Through your access to the session instance, you can obtain all of them in an array with the following:

# Accessing the session variables
$svars = $session->as_array();

To append a new value to the session variables:

# Usage: $session_instance->set($session_key, $value);
$session->set('uid', 1234567890);

To get the value of one:

# Usage: $session_instance->get($session_key, $optional_default_value);
$uid = $session->get('uid', 0);

And finally, to remove:

# Usage: $session_instance->delete($session_key);
$session->delete('uid');

Cookies

Kohana deals only with secure cookies. For this, a string, set-as and referred-as Cookie::$salt must be defined in the bootstrap.php file as the following:

# Usage: Cookie::$salt = 'secure_cookie_key'; 
Cookie::$salt = '1234567890';

To set a cookie value, you can use the same way as you did with Sessions:

# Usage: Cookie::set($cookie_key, $cookie_value);
Cookie::set('uid', 1234..);

To get a cookie’s value:

# Usage: $variable = Cookie::get($cookie_key, $optional_default_value);
$var = Cookie::get('uid', 0);

And finally, to delete:

# Usage: Cookie::delete($cookie_key);
Cookie::delete('uid');

Note: To learn about how to work with cookies using Kohana and more, check out its official documentation (latest edition).

Submitted by: O.S. Tezer

Leave a Reply