Posted In PHP

Basic Routing in PHP with AltoRouter

Routing in PHP using AltoRouter

I’ve been using AltoRouter for help with building simple API’s. A full framework (even a micro-framework), like Slim, is usually overkill for my needs, and often, any kind of routing class is overkill. A .htaccess file with the proper rewrite rules will usually suffice.

When I do need a bit more control than a .htaccess file provides, I usually go with AltoRouter. AltoRouter is really easy to use.

First thing to do when using AltoRouter, or pretty much any PHP routing class/script, is to direct all requests to index.php. We do this with a .htaccess file. Here’s the .htaccess file I usually use with a project using AltoRouter:

That will direct all requests to your site to index.php. Inside index.php is where we setup AltoRouter, define our routing rules, and specify any parameters that we want to capture. A basic example of an index.php file using AltoRouter can be seen below.

Lines 10-15 are just standard routes being setup, we could easily do this with a .htaccess file. The next block, with the “Special” comment title, is a little more involved. But only because we’re passing a parameter or two to our PHP controller.

When I say PHP controller, I’m referencing the third parameter in the AltoRouter map() method. The first parameter is the HTTP request method, usually either GET or POST. The second parameter is the route we want to watch for. The third parameter is the controller, or the PHP file that we want when the route from parameter two is matched. And the fourth parameter is just a unique name for that route.

If you’re using named parameters in your routes, like you see being done on lines 18 and 19 in the index.php gist, you’re going to want to access them within your controller. Notice the very end of the index.php gist, specifically, everything below the /* Match the current request */ comment. That’s where we’re doing the actual matching, if the current URL matches a defined route, then we require the controller.

Before that though, we’re actually setting the $match variable. Since we’re setting $match before including our controller, $match should be available for use within our controller, which is awesome!

Say we’re charging a customer, and this is done by hitting /charge/the_customer_id/, where the_customer_id is an actual customer ID. In our controller, charge.php, we can access the_customer_id named parameter as seen below. It’s available in $match['params']['customer_id'].

You can use all sorts of limits on your named parameters, like integer matching, alphanumeric matching, and even hexadecimal character matching. A useful list of named parameter limits and some examples can be seen in the AltoRouter readme. Comments are open, so please let me know if I’ve missed something or am just totally off base somewhere. Thanks!!

Well, now what?

Work with Me

I'm available for hire and always taking new clients, big and small. Got a project or an idea you'd like to discuss? Startup plan but no developer to make it happen? Just get in touch, I'd love to see if I can help you out!

Leave some Feedback

Got a question or some updated information releavant to this post? Please, leave a comment! The comments are a great way to get help, I read them all and reply to nearly every comment. Let's talk. :) is proudly hosted by DigitalOcean

About these ads
  • DanialThom

    Is there a reason to use rewrite rules rather than just using the Fallbackresource directive?

    FallbackResource /index.php

  • Looks pretty cool. I’ve been using Laravel for a lot of my projects lately and haven’t had the need to rewrite things by myself but I think next time I’m doing a straight PHP project that is a bit more complex but not complex enough for a full framework I would use something like this.

  • Pingback: PHP MVC Skeleton App – Tyler Longren()

  • Ebooky.CZ

    Nice, but what revers routing? Look at this

    $route = new Route(‘/[/]’, ‘Homepage:default’);

    Link in view:
    product detail

    This generate link with URL:

    I would like to see solution for AltoRouter.

    • There is no link creation aspect to AltoRouter. It’s not even close to a full framework like Nette.

      Link creation is one of those things I’d rather my framework didn’t do, most of the time anyway. I can see it’s advantages, but it’s just outside the scope of AltoRouter.

      • Ebooky.CZ

        AltoRouter is super, bud with link creation it would be fantastic. Now you mas generate url and when you change mask router map you mast change format url everywhere .-/

        Now I look on Laravel its look like too good:

        • I stand corrected, Ebooky.CZ. 🙂

          When I wrote this article, there was no link creation/reverse routing available in AltoRouter. Now, however, reverse routing does exist in AltoRouter.

          • Ebooky.CZ

            Yeh super, sorry i dont see it in repository. Thank you very much!

          • Yah I totally missed it, too. I’ll update this post with an example here in a few minutes.

            Danny’s other router, called PHP-Router, has reverse routing, too. I know it didn’t have it last time I looked at it.


  • So simple it hurts – me likey!

  • Thank you for this slim routing system! I’ve just inserted it in my site (I’ve been looking for a solution like this for so long :D)

  • Kuba

    Thanks for this post 🙂

  • Guest

    It does not work on my localhost even though I have followed through the guide. I tried the example file from github, it does not work as well.

  • FX

    How do you deal with an ajax upload file function ?
    Is it possible to ignore certains paths ?

  • Nick

    Thank you sir. Their docs did not explain this well enough for me to start utilizing it. Your examples did that perfectly.

  • This is nice, very simple. Love it. Thanks for the post.

  • Guest

    Does anybody know how to use AltoRouter when third parameter of map method is closure object/function with any practical example?

  • Salfai

    Thank you, it helped me a lot

  • Ds

    Run Xdebug on AltoRouter::match() and just look at the memory useage after say 1000 routes.

    Was enough to make me use something else.

    • Adnan Siddiqi

      For an app with 1k Routes, go for something bigger

  • Mohamed Kara Bernou

    thanks for this awesome example
    I was blocked for 5+ hours for implementing this in my example, which is not OOP or MVC
    the problem was to retrieve $_GET variables
    but finally i found a solution like this :

    $router->map(‘GET’,’/products/[i:id]’, ‘products.php’, ‘products’);

    if($match) {
    $_GET= $match[‘params’]; // here is the magic LOL
    require $match[‘target’];

    so in my (products.php) page i can do something like

    echo ‘You are viewing the product id=’.$_GET[‘id’];

    what do you think ??

  • Purushotam Rawat

    I wish it was more detailed! :/

  • Adnan Siddiqi

    Thanks for the article however I did not get this:


    Which file do I need to include to expose $martch?

  • Dave

    Thank you very much! I’ve been bugged out by the office example from the github but they made it so undesirable. I love your example, and how it automatically includes the file that you need to process that necessary route (just like a redirect on steroids!).