Fork me on GitHub

Routing & Pretty URLs

Default Routing

Default routing is based on typical MVC structure in which URI corresponds to class/method.

        
            http://example.com/blog/list/param1/param2
        
    

In this example the request will be routed to public list method of blogController with param1 & param2 as method arguments. A sample controller would look something like this.

        
            namespace sampleSite\controller
            {
                use hathoora\controller\controller;

                /**
                 * Blog controller
                 */
                class blogController extends controller
                {
                    /**
                     * List action
                     */
                    public function list($param1, $param2, $param3 = null)
                    {
                        //
                    }
                }
            }
        
    

Default Controller

Index page or homepage of an application is routed to defaultController.

        
            http://example.com/
        
    

In this example the request will be routed to public index method of defaultController. A sample controller would look something like the following.

        
            namespace sampleSite\controller
            {
                use hathoora\controller\controller;

                /**
                 * Homepage controller
                 */
                class defaultController extends controller
                {
                    /**
                     * homepage action
                     */
                    public function index()
                    {
                        //
                    }
                }
            }
        
    

Default Action

If you don't specity an action for a controller, then public index method of that controller is called.

        
            http://example.com/blog/
        
    

In this example the request will be routed to public index method of blogController as shown below.

        
            namespace sampleSite\controller
            {
                use hathoora\controller\controller;

                /**
                 * Blog controller
                 */
                class blogController extends controller
                {
                    /**
                     * home action of blog
                     */
                    public function index()
                    {
                        //
                    }
                }
            }
        
    

Camel Case Action Names

Camel case method names are seperated by a dash (-). Consider the following URLs which are both pointing to the same action.

        
            http://example.com/blog/orderBy/name
            http://example.com/blog/order-by/name
        
    

In this example both requests will be routed to public orderBy method of blogController with name as method argument. The code would look like this.

        
            namespace sampleSite\controller
            {
                use hathoora\controller\controller;

                /**
                 * Blog controller
                 */
                class blogController extends controller
                {
                    /**
                     * home action of blog
                     */
                    public function orderBy($type = 'name')
                    {
                        //
                    }
                }
            }
        
    

Note About URI

In above examples routing was based on URI, the part after the domain.

However Hathoora PHP Frameworks allows you to change the domain identifier (using regex patterns) which would change the meaning of URI.

To iterate over this point consider the following application specific configuration.

        
            # File HATHOORA_ROOTPATH/boot/config/app.yml

            app:
                admin:
                    pattern: '^www.example.com/panel/admin(|/)'

                site:
                    pattern: '^www.example.com(|/)'
                    default: true # will be used as default
        
    

Now consider the following URLs to understand the concept and the controller to which they would be routed to:

  • http://www.example.com/blog/list will be handled by app/site/controller/blogController::list
  • http://www.example.com/panel/admin/list will be handled by app/admin/controller/listController::index

Advanced Routing

If default routing is not what you are looking for, then you have two more options for complex routing.

Custom Dispatcher

Custom dispatcher is a PHP class defined per application configuration. To enable it, you need to define dispatcher parameter in configuration as shown below.

        
            # File HATHOORA_ROOTPATH/boot/config/app.yml

            app:
                admin:
                    pattern: '^www.example.com/panel/admin(|/)'
                    # custom routing to be handled by this class
                    dispatcher:
                        class: appDispatcher
                        method: dispatch

                site:
                    pattern: '^www.example.com(|/)'
                    default: true # will be used as default
        
    

In this example requests for site would be handled normally, however requests for admin would be sent to app/admin/appDispatcher::dispatch which must return an array containing:

  • controller e.g. listController
  • action e.g. view
  • array of params e.g. ['title', 'id']

To see advanced routing in action, consider the following sample code:

        
            # File app/admin/appDispatcher

            namespace admin
            {
                /**
                 * Custom request dispatcher
                 */
                class appDispatcher
                {
                    /**
                     * Custom dispatcher for route request
                     *
                     * This function returns array containing:
                     *      - controller class name
                     *      - action name
                     *      - array of params
                     */
                    public function dispatch(\hathoora\container $container)
                    {
                        $arrDispatch = null;

                        $request = $container->getRequest();
                        $routeRequest = $container->getRouteRequest();
                        $uri = $request->serverParam('REQUEST_URI');

                        // URL: /panel/admin/list/12
                        if (preg_match('~admin/list/(\d+)~i', $uri, $arrMatches)
                        {
                            $arrDispatch = array(
                                'controller' => 'listController',
                                'action' => 'view',
                                'params' => array(array_pop($arrMatches));
                        }
                        else
                        {
                            // following is the same as default routing
                            $arrUriParts = explode('/', $uri);
                            array_shift($arrUriParts);
                            $firstPart = array_shift($arrUriParts);

                            $arrDispatch = array(
                                'controller' => 'questionsController',
                                'action' => $firstPart,
                                'params' => $arrUriParts);
                        }

                        return $arrDispatch;
                    }
                }
            }
        
    

Apache (or other web servers) Rewrites

You can also use Apache rewrite for routing URLs. You would need to set the following params in Apache:

  • REDIRECT_HTRO
  • REDIRECT_HTRO_CONTROLLER
  • REDIRECT_HTRO_ACTION
  • REDIRECT_HTRO_PARAMS

The following example routes a URL http://mysite.com/posts/1-hello-world to postsController::view($id, $slug).

        
            # File: docroot/.htaccess

            RewriteEngine On

            # Fancy URL for viewing a post on domains
            RewriteCond %{HTTP_HOST} ^mysite.com [NC]
            RewriteCond %{REQUEST_URI} ((.+?)|)/posts/(\d+)(-\/?(.+?))$ [NC]
            RewriteRule .* index.php  [E=HTRO:1,E=HTRO_CONTROLLER:postsController,E=HTRO_ACTION:view,E=HTRO_PARAMS[0]:%3,E=HTRO_PARAMS[1]:%5,E=HTRO_PARAMS[2]:%2,L,QSA]
        
    

At this moment, it is not possible to set appname using this method.

Page Took:         5.42 msec
Page Memory:   534.08k
docs / viewController / view (200)
Request UUID: 5a2e4bbaa37605.46829213
Get
Post
Cookies
Files
Session
Server
Response
No data.
No data.
No data.
No data.
No data.
REDIRECT_HATHOORA_ENV
prod
REDIRECT_STATUS
200
HATHOORA_ENV
prod
HTTP_HOST
www.hathoora.org
HTTP_X_FORWARDED_FOR
54.221.93.187
HTTP_X_REAL_IP
54.221.93.187
HTTP_CONNECTION
close
HTTP_ACCEPT_ENCODING
x-gzip, gzip, deflate
HTTP_USER_AGENT
CCBot/2.0 (http://commoncrawl.org/faq/)
HTTP_ACCEPT
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
HTTP_IF_MODIFIED_SINCE
Thu, 19 Oct 2017 20:11:56 GMT
PATH
/sbin:/usr/sbin:/bin:/usr/bin
SERVER_SIGNATURE
Apache/2.2.15 (CentOS) Server at www.hathoora.org Port 80
SERVER_SOFTWARE
Apache/2.2.15 (CentOS)
SERVER_NAME
www.hathoora.org
SERVER_ADDR
192.168.1.11
SERVER_PORT
80
REMOTE_ADDR
207.126.164.119
DOCUMENT_ROOT
/var/websites/hathoora.org/docroot
SERVER_ADMIN
webmaster@hathoora.org
SCRIPT_FILENAME
/var/websites/hathoora.org/docroot/index.php
REMOTE_PORT
56742
REDIRECT_URL
/docs/v1/routing
GATEWAY_INTERFACE
CGI/1.1
SERVER_PROTOCOL
HTTP/1.0
REQUEST_METHOD
GET
QUERY_STRING
REQUEST_URI
/docs/v1/routing
SCRIPT_NAME
/index.php
PHP_SELF
/index.php
REQUEST_TIME_FLOAT
1512983482.668
REQUEST_TIME
1512983482
Status: 200
Headers:
Content-Type
text/html; charset=UTF-8
Configutation
Key Value
app.admin
Array
(
    [pattern] => /admin(|/)
    [directory] => hathoora
    [namespace] => hathoora\admin
)
app.docs
Array
(
    [pattern] => /docs(|/)
    [directory] => hathoora
    [dispatcher] => Array
        (
            [class] => customDispatcher
            [method] => dispatch
        )

)
app.site
Array
(
    [default] => 1
)
hathoora.logger
Array
(
    [profiling] => Array
        (
            [enabled] => 1
        )

    [logging] => Array
        (
            [enabled] => 1
            [level] => DEBUG
        )

    [webprofiler] => Array
        (
            [enabled] => 1
            [system] => 
            [show_redirects] => 
        )

)
hathoora.template
Array
(
    [engine] => Array
        (
            [name] => Stuob
        )

)
hathoora.database
Array
(
    [default] => mysql://dbuser:dbpassword@dbhost:3306/dbname
)
services.container
Array
(
    [class] => \hathoora\container
    [method] => getContainer
)
Logging (14)
hathoora.logger.logging.enabled: 1
# Time (msec) Level Memory (KB) Message
1 2.280 DEBUG 309.77 Configuration loaded:
Array
(
    [0] => app_prod.yml
    [1] => config_prod.yml
)
2 2.554 DEBUG 323.38 Listener "kernel.terminate[webprofiler]" has been added because of hathoora.logger.webprofiler.enabled
3 2.733 DEBUG 326.77 Event kernel.ready has been registered.
4 2.941 DEBUG 335.13 Calling App dispatcher (Array ( [class] => customDispatcher [method] => dispatch ) )...
5 3.122 DEBUG 349.55 Event kernel.route has been registered.
6 3.382 DEBUG 378.91 Event kernel.controller has been registered.
7 3.432 DEBUG 379.85 Calling controller (\docs\controller\viewController::view) with following params
Array
(
    [0] => v1
    [1] => routing
)
8 4.047 INFO 467.20 Template (docs/v1/routing.tpl.php) loaded
9 4.242 INFO 495.12 Template (/var/websites/hathoora.org/app/hathoora/docs//resources/templates/components/htmlMeta.tpl.php) loaded
10 4.339 INFO 496.37 Template (/var/websites/hathoora.org/app/hathoora/docs//resources/templates/components/flashMessages.tpl.php) loaded
11 5.246 INFO 444.71 Template (docs.tpl.php) fetched.
12 5.272 DEBUG 444.30 Event kernel.response has been registered.
13 5.290 DEBUG 445.49 Event kernel.terminate has been registered.
14 5.336 DEBUG 448.71 Event kernel.terminate->webprofiler has been notified.
Profiling
template
# Time (msec) Name Cached Took (msec)
1 3.543 docs.tpl.php 0 1.651