License NuGet release Packagist release Packagist pre-release NuGET downloads Packagist downloads

2.0: Release build status Release code quality develop: Dev Build Status SensioLabsInsight master: Mater Build Status

Table of Contents

What is this?

AloFramework is an incredibly lightweight and flexible MVC framework for PHP 5.4+. It has a lot of built-in functionality including but not limited to:

  • Memcached wrapper
  • Database connection class
  • MySQL,Redis or Memcached-based session managers
  • HTML form validator
  • Code testing suite
  • Email sender
  • Crontab editor
  • Object-oriented cURL wrapper
  • Object-oriented file manager
  • Remote SFTP file manager
  • Code profiler
  • CLI tools
  • Localisation tools
  • File management utilities



This product is licenced under the GNU General Public Licence Version 3




You will find code documentation under the docs directory, some setup scripts under setup and source files under src. In src the main components are app*, resources, sys** and files under the directory root.

  • sys contains all the framework files
  • resources is where you're meant to put all your images, css and whatnot
  • app is where your code should go
  • .htaccess.sample contains the contents for mod_rewrite: if you have access to your web server's file system copy these to the global config file. If not, rename it to .htaccess.
  • index.php contains some core constants



The class, trait and interface directories found under src/app and src/sys follow a namespaced structure, e.g. the class Alo\Db\MySQL would be found in the file class/alo/db/mysql.php. Please not that all directory and file names should be lowercase.



Main concept

For most projects, you will want to write your own classes that extend those of the framework's. That way you will be completely safe from losing any code during a framework upgrade. The built-in autoloader will automatically load any required interfaces found in app/class, app/interface, sys/class and sys/interface.


The global Alo class

This class is always loaded by default and contains static references to objects which are in most cases used as singletons. You should try to load most of your classes into its static properties, e.g. you will usually only need one database connection, so you can assign it to Alo::$db and access it from anywhere in your code.



All controllers must go under app/controllers (accessible via the DIR_CONTROLLERS method), have the Controller namespace and extend the class Alo\Controller\AbstractController. To make this easier, you can write your own Abstract controller and extend that of Alo\ from within, for example:


namespace Controller;

class AbstractController extends Alo\Controller\AbstractController {
   //Your code


namespace Controller;

class Home extends AbstractController {
   //Your code

Only public, non-abstract, non-static methods will be used for routing. The default method for most controllers is index(). Controllers can be in any of DIR_CONTROLLERS' subdirectories.



Any view can be loaded via Alo\Controller\AbstractController's protected method loadView:

  * Loads a view
  * @author Art <a.molcanovas@gmail.com>
  * @param string  $name   The name of the view without ".php".
  * @param array   $params Associative array of parameters to pass on to the view
  * @param boolean $return If set to TRUE, will return the view, if FALSE,
  *                        will echo it
  * @return null|string
  protected function loadView($name, $params = [], $return = false) {
     // Code

This will load a view under app/view/$name.php. You can provide parameters to pass on to the view via $params, e.g. if you pass on ['foo' => 'bar'] and echo $foo in the view, the output will be bar. If instead of echoing the output you want to retrieve it, provide $return with true. Each view can be reused during the same execution.


Global Autoload

You can create app/core/autoload.php which will be loaded before your controller is initialised. Use this file for any global includes in your project.



All routing is done in the router.php config file. By default, if a route is not found, the router will look in your controllers directory's root for an automatically calculated route: www.domain.com/controller/method/arg1/arg2[...]/argN. This can be overwritten in the $routes array, where the array keys are case-insensitive regular expressions for the request URI (without delimiters or modifiers) and the values are configuration arrays containing the following keys (bold values mean the default values if the key is not set):

  • dir => the controller subdirectory [./]
  • class => which controller class to load [$default_controller] or URL-based
  • method => which method to load [index or URL-based]
  • args => array of arguments to pass on to the method. These can be hardcoded values or placeholders ('\$1', '\$2' etc) which will replace items in the regular expression (key). [empty array]



All logging is done via the global static class \Log's public methods - please refer to the documentation. You will can set the logging level (during the Initial Setup phase described below).


Session Management

There are several session management wrappers available, all of which implement the standard SessionHandlerInterface. To use a manager of your choosing (located under the Alo\Session namespace) simply call the corresponding manager's static init() method, e.g.:

use Alo\Session\MemcadhedSession;
use Alo\Session\RedisSession;
use Alo\Session\MySQLSession;

MemcachedSession::init(); // initialise Memcached session
RedisSession::init(); // or a Redis session
MySQLSession::init(); // or a MySQL session

The session managers are dependent on the MySQL, RedisWrapper and MemcachedWrapper respectively. These can be assigned to Alo::$db or Alo::$cache or passed on as a reference to the init() method. There is no need to call session_start() as the handler does this for you.



Localisation is handles via Alo\Locale. After you've loaded the table (from the SQL file in the setup directory) call the fetch() method, specifying the page IDs to pull. If using ALO_LOCALE_FETCH_ALL, this parameter does not matter. After the fetch you can access your keys via __get(), i.e. to get the key 'foo' use echo $localeInstance->foo.


Initial setup

  • You will want to copy the contents of sys/config into app/config. Open them and set the values as appropriate.
  • Open index.php, scroll to // ===== General setup BEGIN ===== and set the values as you please.
  • Next you'll want to run the appropriate files under setup if you are using that functionality.
  • If you have access to your web server's file system, copy the contents of .htaccess.sample to the configuration file; if you don't, rename it to .htaccess



Updates are applied by following these 6 steps:

  1. Look through the changelog for to see if any changes will cause issues (e.g. a deprecated method being removed), prepare your code if necessary.
  2. Make a copy of your index.php file.
  3. Delete the above, as well as the sys directory.
  4. Extract the new code. It will never contain files other than blank index.htmls and sample.phps under app/, so no application code will be overwritten.
  5. If there are any changes to .htaccess.sample, merge them with your version.
  6. Re-apply your personal settings under index.php's // ===== General setup BEGIN =====


Running tests

When running PHPUnit tests be sure to use the phpunit.php bootstrap file from the root directory. It will make sure that all classes are loaded correctly and that the framework behaviour is altered to not interfere with the tests. Please note that in PHPUNIT mode the framework does not automatically initialise the Router - you will have to run the code below to test a controller:

$router = new \Alo\Controller\Router();
$router->init(); //Or ->initNoCall() if you just want to initialise it, but not call the relevant controller


Latest changes

See changelog.md for a full changelog of previous versions.

2.0 (2015-06-21)

Added features

  • Localisation support added! See README.md
  • LOG_LEVEL_WARNING is now defined in index.php and is the default logging level. Log::warning() method introduced.

Bugs fixed

  • MemcachedWrapper->getAll() now returns correct results when running the Windows version of Memcache
  • AbstractDB can now reuse Alo::$cache instead of instantiating a new class

PSR-1 standards-compliant renames

Code review required:

  • Global functions
  • server_is_windows() --> serverIsWindows()
  • timestamp_precise() --> timestampPrecise()
  • lite_debug() --> debugLite()
  • escape_html5() --> escapeHTML()
  • AbstractController
  • http_error() renamed to httpError()
  • Router
  • Gettable variables renamed in camelCase (applies to getters too)
  • is_cli_request() --> isCliRequest()
  • is_ajax_request() --> isAjaxRequest()
  • Config file
    • $error_controller_class --> $errorControllerClass
    • $default_controller --> $defaultController
  • Alo
  • $form_validator --> $formValidator
  • Log
  • log_level() --> logLevel()
  • IO
  • echo_lines() --> echoLines()
  • open_file_default() --> openFileDefault()
  • AbstractCache
  • is_available() --> isAvailable()
  • Format
  • is_ipv4_ip() --> isIpv4()
  • Email
  • is_email() --> isEmailAddress()
  • Security
  • un_xss() --> unXss()
  • ascii_rand() --> asciiRand()
  • File
  • convert_size() --> convertSize()
  • get_extension() --> getExtensionStatically()
  • Curl
  • setopt_array() --> setoptArray()
  • Profiler
  • diff_on_key() --> diffOnKey()

No code review required:

  • Static constructors are now in camelCase - no implications as of PHP 5.6.9

Config constants

  • ADDED | ALO_SESSION_SECURE: Determines whether the session cookie should only be sent via SSL.
  • ADDED | ALO_MYSQL_CHARSET: Determines the connection charset.
  • ADDED | ALO_SESSION_HANDLER: Determines which session handler will be used


  • Global shorthands added for trigger_error():
    • phpError($msg)
    • phpWarning($msg)
    • phpNotice($msg)
    • phpDeprecated($msg)

Major functionality changes

  • Sessions
  • SQLSession, Alo::$session & Alo::loadSession() have been removed
  • Sessions are now invoked via the handler's static init() method, e.g. to initialise a MySQL session you would call MySQLSession::init(). Any dependencies' instances, e.g. MySQL or RedisWrapper can be passed as a parameter or used from Alo::$db/Alo::$cache respectively
  • The session handler to be used will is now defined in config/session.php with ALO_SESSION_HANDLER
  • Sessions will now be used in the standard PHP way of $_SESSION. There is no need to do session_start(), only ::init().

Removed deprecated items

  • Alo\File
  • Testing suite
  • FileException

Misc Functionality/feature changes

  • Most classes now have self::$this so you can globally reference their last instances - useful for singletons.
  • SampleErrorController->error()'s $message parameter removed as it was unused
  • AbstractController->httpError() no longer has a die() statement to stop script execution once called. It only suppresses output now.
  • MemcachedSession, RedisSession and MySQLSession constructors now throw a LibraryException instead.


  • A plethora of code quality improvements with the help of SensioLabs Insights
  • Sample .htaccess file renamed to .htaccess.sample


External Libraries

AloFramework uses the following external libraries for its functionality:


Supporting the Project

Any support is greatly appreciated - whether you're able to send a Paypal donation, become a ClixSense referral or simply drop an email I'll be very grateful. :)


Other Alo Products

You can find other products of mine at alorel.weebly.com