NanoMVC

Controllers

What is a controller?

Controller files are what glue the application together. They load models, display views, and tie in the plugins and application library code. They are the content traffic cops, so to speak.

A typical URL to a NanoMVC page looks like this:

http://[host]/​index.php/​[controller]/​[action]/[param1]/​[param2]/[param3...]

Where the [controller] is the name of the controller file/class, and [action] is the method name you want to access. Additional values are used as parameters.

Example:

http://localhost/​index.php/hello/​intro/name/joe

Learning by example

Controller files live in the /myapp/controllers/ directory. Let's create a controller:

/myapp/
  /controllers/
    hello.php
class Hello_Controller extends NanoMVC_Controller {
  function index() {
    echo "Hello World.";
  }
}

Note: Ideally, controllers should not contain echo statements or any direct output. The example above is a basic demonstration. Proper examples using views are available in the Views section.

The controller name in the URL is case-insensitive and should not include the .php extension.
The controller file must always be named in lowercase (e.g. default.php). Inside the file, the controller class must end with the suffix _Controller, and the class name casing does not matter.

You can request a controller using any casing in the URL, such as /Default, /DEFAULT, or /default — all will resolve to the same controller file.

Inside controller methods, you can retrieve the controller name as it was written in the URL using:

$this->_get_controller();

This will reflect the original casing, such as default, Default, or DEFAULT.

To get the controller class name as defined in code (with its original casing), use the PHP magic constant:

echo __CLASS__;

Example: Default_Controller

Now visit:

http://localhost/index.php/hello

You should see Hello World. in your browser.

If no controller is specified in the URL, default is assumed. This can be changed in /myapp/configs/config_application.php. See the "Default Controller" section below.

Now let’s add another method to our controller:

class Hello_Controller extends NanoMVC_Controller {
  function index() {
    echo "Hello World.";
  }

  function time() {
    echo "The time is now.";
  }
}

Then access it via:

http://localhost/​index.php/hello/time

As you can see, appending the method name executes the corresponding method.

If no method is given, the default index method is used.

Removing index.php from the URL

You can clean up the URL using this Apache rewrite rule:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]

Place this in your .htaccess or server config. Then, instead of /index.php/hello you can simply use:

http://localhost/hello

Make sure to add a robots.txt and favicon.ico file to avoid unnecessary rewrites when bots or browsers request those resources.

About Method Case Sensitivity

Controller method names in NanoMVC are case-insensitive, as defined by PHP itself.
You can call:

— all will resolve to the same method.

However, PHP does not allow declaring two methods that differ only by case (e.g., index() and Index()).

To handle case-specific logic, you can use the method name as defined in the controller using __FUNCTION__ and compare it to the original method name extracted from the URL in your router.

To get the action name from the URL, use the _get_action() method. See the example below:

class Case_Controller extends NanoMVC_Controller {
  function Index() {
    if (__FUNCTION__ === $this->_get_action())
      echo 'the same';
    elseif ($this->_get_action() === 'INDEX')
      echo 'CAPS';
    elseif ($this->_get_action() === 'index')
      echo 'lower';
    else
      throw new Exception("Unknown controller method '{$this->_get_action()}'");
  }
}

Allowed Characters in Names

Controller and method names must contain only word characters: [a-zA-Z0-9_]. Any name containing special characters, spaces, or symbols outside of this pattern will be rejected and may cause routing errors.

This constraint ensures predictable routing and avoids issues with file naming and method resolution in PHP.

Uncallable Methods

In NanoMVC, certain methods cannot be called directly via a URL. These are called uncallable methods, and their names start with an underscore (_).

This behavior is inherited from TinyMVC and is reserved both for internal system use and user-defined helpers. You can safely define private or utility methods inside your controllers with a leading underscore, knowing they won't be exposed to routing or executed externally.

class User_Controller extends NanoMVC_Controller {
  function profile() {
    $this->_log_access(); // call internal helper
    $this->view->display(​'user_profile_view'); // show the view
  }

  function _log_access() {
    // This method cannot be accessed from URL
    // but is available internally
  }
}

Default Controller

If no controller is given in the URL, NanoMVC uses the default controller and the index action by default.

You can customize this here:

/nanomvc/
  /myapp/
    /configs/
      config_application.php
/* name of default controller/method when none is given in the URL */
$config['default_controller'] = 'mycontroller';
$config['default_action'] = 'myaction';

Root Controller

If you want to force all requests to go through a specific controller and method regardless of the URL, you can configure that here:

/nanomvc/
  /myapp/
    /configs/
      config_application.php
/* set this to force controller and method instead of using URL params */
$config['root_controller'] = 'myroot';
$config['root_action'] = 'myaction';

The root_controller takes precedence over the default controller and overrides any controller provided in the URL.

Both root_controller and root_action can be used independently. For example, you may want to override only the action globally, but keep the standard controller logic from the URL.

URL Routing

You can route or map user-friendly URLs to other internal URLs using the routing feature. This is done by providing arrays of regular expression patterns and their replacements, compatible with preg_replace().

/nanomvc/
  /myapp/
    /configs/
      config_application.php
/* URL routing, use preg_replace() compatible syntax */
$config['routing']['search'] = array('!/foo/(\d+)!');
$config['routing']['replace'] = array('/foo/index/${1}');

This example rewrites /foo/123 into /foo/index/123 before routing to the controller.

You can use a wide range of regular expressions beyond \w to match various characters. For example, you can also match dashes, uppercase words, symbols, or specific strings.

$config['routing']['search'] = [
  '!/default-test/([\w-]+)-route!', // 1
  '!/angry/path!'                   // 2
];
$config['routing']['replace'] = [
  '/default/route/${1}',            // 1
  '/default/route/angry/path'       // 2
];

These examples:

Keep in mind that the resulting rewritten URL must point to a valid controller and method in your application.

← to Installation to Views →

← Back to Documentation