Singleton pattern

Singleton class is class that allow only one instance of its class to be instantiated.

A lot of examples I see the way to implement singleton pattern whether:

1. Extends a base singleton class
2. Each class apply singleton pattern (get_instance() method, has static $instance attribute)
3. Using registry pattern where one dedicated class act as the singleton instances manager

Well, things shouldn’t get too hard. Here, I will use the combination of registry pattern and singleton in just a function

function o($class) {
    static $instances;
    if (!isset($instances[$class]) || !$instances[$class] instanceof $class) {
        $instances[$class] =& new $class();
    }
    return $instances[$class];
}

To use it:

o('db')->query(...);
o('db')->fetch();
o('singleton_class')->do_something();

PHP Hooks System

After reading Explaining Hooks, finally I understand the concept of hooks in PHP and why people use it in WordPress and say WP codes is poetry.

The general idea is, in a web application, during the runtime of the program it go through stages of processes, such as connecting to database, start the session, rendering template etc. These are known as events. When these events occured during the runtime of the program, some external code can be run as additional processing to the core program. These external/additional process is known as plugin.

So, the hooks system expose these events for the plugins to attach to. So that when the event occur, the plugin will be run. Even though the concept seems simple, but there are problem that we need to handle:

Which plugin to call first when this event occur? The hooks system need to have priority feature to make sure plugins are called in correct order, to produce the intended result

What plugin need to load? If load all, wouldn’t it affect the site performance? This is why plugins need to be registered to the plugins system of an application. So that, the core application know what plugins to load at what time, and what function to run.

Therefore, the hooks system need to have plugin registration section, priority section, specify the list of hooks event available and know how to handle unknown events. The plugin data can be stored in database, and stored the configuration data temporarily in cache for faster access.

Cloudflare & phpBB3

Session handling in phpBB3 requires a user to use one IP address per session, therefore if your IP address changed, you will be prompt to login again.

Cloudflare is a web caching service that cache static contents of a website by acting as the nameserver that manage the website domain name. Therefore, every request to the domain name will pass through Cloudflare system first and any cached contents will be served from Cloudflare servers instead of the web hosting server.

However, when using Cloudflare service, the REMOTE_ADDR value for PHP $_SERVER will follow Cloudflare servers IP address. Therefore, you might face problem when using phpBB (or any other web app that rely on session tied to the IP address) with this service.

So, we need to edit phpBB session.php file to grab the correct variable for the users’ real IP address. Edit includes/session.php

Find:

$this->ip = (!empty($_SERVER['REMOTE_ADDR'])) ? (string) $_SERVER['REMOTE_ADDR'] : '';

Replace with:

$this->ip = (!empty($_SERVER['HTTP_CF_CONNECTING_IP']))
          ? (string) $_SERVER['HTTP_CF_CONNECTING_IP']
          : ((!empty($_SERVER['REMOTE_ADDR'])) ? (string) $_SERVER['REMOTE_ADDR'] : '');

HTTP_CF_CONNECTING_IP is special header value passed by Cloudflare servers containing visitors’ real IP address, and in case this variable not set, we use the good ol REMOTE_ADDR

phpBB SEO Ultimate URL backslash in URL

In case someone stumbled upon this problem:

1. You download and install the new release of phpBB (3.0.9) and immediately integrate SEO Ultimate URL package
2. The setup went well except you found out that the page is looked ugly because the CSS wasn’t loaded – cause by the URL got backslash in it:

http://localhost//style.php …

To fix, you need to edit the data in the config table:
1. Access the phpBB3 config table (phpbb_config)
2. Lookup for config_name = ‘script_path’
3. You’ll see the value is ‘/’. Change this to ‘/’
4. Save the data

Clear the cache, and reload the page. You should see the pretty page back again!

Additional: I’m using localhost with custom port number (82) as testing platform. So in case you’re not getting the image out on the page (caused by the URL generated become http://localhost/style… instead of http://localhost:82/style…, so you need to edit the force server URL settings

1. Go to admin control panel, General > Server Settings
2. Set ‘Force Server URL’ to ‘Yes’

PHP Data Validation

WordPress data validation has some good reference in doing data validation, especially the philosophy part. For best practice, always use format correction first, then use whitelist.

// format correction
$action = (int) $_GET['action'];
// whitelist
switch ($action) {
    case 1:
        do_this();
        break;
    case 2:
        do_that();
        break;
    case 0:
    default:
        die("Don't know this action!");
}

However the above example is only for one input ($_GET[‘action’]). What if your web app (or controller) need  a few inputs, and surely you don’t want to write the same code over again, like this

// correct the format
$id = (int) $_GET['id'];
$name = (string) trim($_POST['name']);
$email = (string) trim($_POST['email');
$about = (string) htmlspecialchars(trim($_POST['about']), ENT_QUOTES, 'UTF-8');
// then do validation
if ($id == 0) {
    $id = 1;
}
if (empty($name)) {
    $msg = 'Name is required';
}
...

Most PHP frameworks I know whether validate the input one by one or using just one input source (GET or POST or COOKIE). It’s better to use $_REQUEST, since some input can be passed in <form> or just query string. E.g. /blog/post/?id=10&do=edit, then inside the page got <input type="hidden" name="do" value="save" />, now you can use both input from $_REQUEST[‘do’], which determine what action need to be done

$do = (string) $_REQUEST['do'];
switch ($do) {
    case 'edit':
        get_post($id);
        break;
    case 'save':
        save_post($id);
        break;
    case 'view':
    default:
        view_post($id);
        break;
}

With that pattern, here comes PHP filter functions, filter_input_array(). It receive an array of arguments, and source type (GET/POST etc.) and validate each of the input. It will return false on failed validation. This function is really convenient when we need to validate a long list of inputs.

However there’s a drawback. Since all the validation can be put in one input key argument (‘input_name’ => array(…list of various validators…), it is difficult to provide accurate error message, of which validation that failed. Therefore we can recreate another filter_input_array(), and put in the previous pattern (format first, then whitelist) into it. So basically the validation function work like this:

$input = validate_input(array(
    'id' => array('filter' => 'int', 'options' => array(
        'range' => array('max' => 1000, 'msg' => 'Max. value for ID is 1000')
    )),
    'name' => array('filter' => 'string', 'options' => array(
        'required' => array('value' => true, 'msg' => 'This input is required'),
        'alphanumeric' => array('value' => true, 'msg' => 'Name need to be alphanumeric')
    ))
));
// now we can use $input
$input['id'];
$input['name'];
// to get error msg
$err_msg['id']; // which may contain the error msg of specific validator
$err_msg['name'];
// to check if the whole form passed the validator or not, simply:
if (empty($err_msg)) {
    // form is valid
}

Additional note: String input.

To sanitize the string input, actually trim() is enough, and can be directly stored in database. You only need to sanitize the value only when outputting it. When echo() the value to HTML, make sure to always encode it first:

<p class="comments"><?php echo htmlspecialchars($value, ENT_QUOTES, 'UTF-8'); ?></p>

This not only can prevent XSS issue, but also display the correct Unicode character. Avoid htmlentities() as it may corrupt the Unicode characters

Page Controller Pt.2

However, as the web application grow, the controller part may become very complex. As we know, a web page is a collection of sections which combined together to become a page – header, sidebar, main content, footer, banner etc. are sections (or whatever you call it). Therefore, it would be very complex when we need to include all this in a single controller. We can separate the smaller sections to another class or put it in our toolbox functions class, but it might be temporary before you may need it to act like a main controller. Here’s where the difference comes:

  • Most framework (that I know) only consist of single MVC, which designed to handle one simple request (CRUD operation of a blog post is a simple request)
  • A way to overcome this is by abstracting similar logics to a parent class, and let controller extends it. However not all conditions require those extra logics to be loaded for all requests.

Then I read http://techportal.ibuildings.com/2010/02/22/scaling-web-applications-with-hmvc/, an extension to ordinary MVC. It’s a collection of MVC triad that are independent to each other, and one MVC become the main controller. By using this idea, we can redesign our front controller to support HMVC and make it ready for a complex application

  1. Front controller received request, parse, delegate to target page controller as usual, and run the target controller.
  2. From within main controller, we may call another controller for different sections in that particular page.
  3. All sub controllers that being called from main controller will be independent of each other – make it look like requesting a different page. We may call it asynchronously (from within PHP, using cURL and get the response in whatever format)
  4. These subcontrollers doesn’t need to be reside in the same server or same script directory with the main controllers, it can be put in different server and act as a background service, interact using RPC, SOAP or other web service protocol

What’s more interesting is all these can be achieved without having to allocate too much resource as in term of development time (all can be done in PHP), server (one server can achieved all these) and maintainability (all components are structured and modularized – given you’re writing proper documentation and comments on the code). Take a look at Kohana or CodeIgniter if you’re interested to include this feature into your web application.

Page Controller

Having read http://www.phpwact.org/pattern/centralized_request_logic, one thought comes to mind, which one the better preferred way to code the page controller for PHP.

The page controller is the common pattern, where a file handles one web page and all of its actions. Files are being accessed directly. Base class usually being used to refactor the code. E.g http://domainname.tld/about.php, http://domainname.tld/search.php – these php files are independent from each other. Older PHP scripts are using this method, and it’s quite hard to maintain the code.

Intercepting filters being implemented by prepend the page controller script with an input filter script and append it with an output filter.  These controllers will include a header file (input filter) at the beginning of the script and include a footer file (output filter) to the end of the script. Having need to include the filter files on every page we created is quite cumbersome, and also the filter files need to handle many types of request, and sometimes the page controllers doesn’t need all of those extra functions to handle specific requests. phpBB is one of the PHP scripts that using this pattern.

Front controller pattern is having one central point to accept request and dispatch it to appropriate page controllers. This is common for all modern framework such as CakePHP, YiiFramework and DooPHP. Also these frameworks utilize the dynamic invocation method, where it doesn’t store the registry of modules and plugins it has – the framework will lookup the script directory to find appropriate controllers to handle the request. It is a drawback for static invocation method since it stores a large list of modules or plugins which need to be loaded on every requests, and it surely not needed all the time by all of the controllers.

Therefore, I conclude that the best way to code the page controller is by implementing dynamic invocation of front controller, similar to other frameworks. Here’s the program flow:

  1. Front controller received a request.
  2. Parse the request to determine which page controller to load, which action to run and what parameter need to be set
  3. Load target controller or show error page not found
  4. Target controller will need to extend some base class that share same logic with other controllers.
  5. Run the target action, determine  how to display the output