The simple PHP router

Overview

Macaw

Macaw is a simple, open source PHP router. It's super small (~150 LOC), fast, and has some great annotated source code. This class allows you to just throw it into your project and start using it immediately.

Install

If you have Composer, just include Macaw as a project dependency in your composer.json. If you don't just install it by downloading the .ZIP file and extracting it to your project directory.

require: {
    "noahbuscher/macaw": "dev-master"
}

Examples

First, use the Macaw namespace:

use \NoahBuscher\Macaw\Macaw;

Macaw is not an object, so you can just make direct operations to the class. Here's the Hello World:

Macaw::get('/', function() {
  echo 'Hello world!';
});

Macaw::dispatch();

Macaw also supports lambda URIs, such as:

Macaw::get('/(:any)', function($slug) {
  echo 'The slug is: ' . $slug;
});

Macaw::dispatch();

You can also make requests for HTTP methods in Macaw, so you could also do:

Macaw::get('/', function() {
  echo 'I'm a GET request!';
});

Macaw::post('/', function() {
  echo 'I'm a POST request!';
});

Macaw::any('/', function() {
  echo 'I can be both a GET and a POST request!';
});

Macaw::dispatch();

Lastly, if there is no route defined for a certain location, you can make Macaw run a custom callback, like:

Macaw::error(function() {
  echo '404 :: Not Found';
});

If you don't specify an error callback, Macaw will just echo 404.


In order to let the server know the URI does not point to a real file, you may need to use one of the example configuration files.

Example passing to a controller instead of a closure


It's possible to pass the namespace path to a controller instead of the closure:

For this demo lets say I have a folder called controllers with a demo.php

index.php:

require('vendor/autoload.php');

use NoahBuscher\Macaw\Macaw;

Macaw::get('/', 'Controllers\demo@index');
Macaw::get('page', 'Controllers\demo@page');
Macaw::get('view/(:num)', 'Controllers\demo@view');

Macaw::dispatch();

demo.php:

<?php
namespace Controllers;

class Demo {

    public function index()
    {
        echo 'home';
    }

    public function page()
    {
        echo 'page';
    }

    public function view($id)
    {
        echo $id;
    }

}

This is with Macaw installed via composer.

composer.json:

{
   "require": {
        "noahbuscher/macaw": "dev-master"
    },
    "autoload": {
        "psr-4": {
            "" : ""
        }
    }
}

.htaccess(Apache):

RewriteEngine On
RewriteBase /

# Allow any files or directories that exist to be displayed directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^(.*)$ index.php?$1 [QSA,L]

.htaccess(Nginx):

rewrite ^/(.*)/$ /$1 redirect;

if (!-e $request_filename){
	rewrite ^(.*)$ /index.php break;
}

Comments
  • Redirect

    Redirect

    I have tried several different ways to redirect with no success.

    For example after a login

    Url::redirect('dog/indexadmin');
    

    And that method:

        public static function redirect($url = null, $fullpath = false, $code = 200)
        {
            $url = ($fullpath === false) ? DIR . $url : $url;  // tried commenting out
            if ($code == 200) {
                header('Location: ' . $url);
            } else {
                header('Location: ' . $url, true, $code);
            }
            exit;
        }
    

    DIR is just /mini4/. Tried without it. Also have tried many combinations:

    Url::redirect('dog/indexadmin');
    Url::redirect('/dog/indexadmin');
    Url::redirect('http://localhost/mini4/dog/indexadmin');
    Url::redirect('/mini4/dog/indexadmin');
    Url::redirect('mini4/dog/indexadmin');
    

    I just cannot seem to do a redirect.

    If I, after logging in type the url in the address bar, it works, so routing is working, but no redirects.

    The redirect method is from SMVC framework, from David Carr. But I even tried direct redirects using:

    $url = 'dog/indexadmin';
    header('Location: '.$url);  // tried all the above in the variable.
    die;
    

    Please help.

    opened by jimgwhit 10
  • Routing Issues

    Routing Issues

    I am attempting to test Macaw on localhost:8080 with the built-in PHP server using a router script as shown here:

    http://php.net/manual/en/features.commandline.webserver.php#example-383

    The issue is that no url except the root ('/') is matching. Even if I have defined a route by:

    Macaw::get('/test', function () {
        echo 'this is a test';
    });
    

    It gives me 404. Only the route:

    Macaw::get('/', function () {
        echo 'hello';
    });
    

    actually seems to be working. I also get a warning: undefined offset "1" on line 73, if that helps.

    Thanks.

    opened by amilios 9
  • Always outputs 404, not a single route works

    Always outputs 404, not a single route works

    Although I've proper configuration ( checked & reconfigured ), it fails to route. It always prints '404' only. I found a older version of it may be, and checked that, it was working. Whats the problem, how to fix it? And can we have a changelog? so that I can check which features I have in the older version and which Im missing..

    opened by FarhanShares 8
  • combined pattern problem?

    combined pattern problem?

    hi,

    i try to route some blog entrys like /post/2014/01/27/some_blog_entrys but i think only the first entry on the str_replace matched?

    my code is like:

    Router::get('/post/(:num)/(:num)/(:num)/(:any)', function($year,$month,$day,$headline) {
        echo "Year". $year . "<br/>";
        echo "Month". $month . "<br/>";
        echo "Day". $day . "<br/>";
        echo "Headline". $headline . "<br/>";
    });
    

    output is this:

    Year2014
    Month
    Day
    Headline
    
    27.01.2014,15:44:29,Missing argument 2 for {closure}(),/Applications/xampp/xamppfiles/htdocs/devlist/app/routes.php,18
    27.01.2014,15:44:29,Missing argument 3 for {closure}(),/Applications/xampp/xamppfiles/htdocs/devlist/app/routes.php,18
    27.01.2014,15:44:29,Missing argument 4 for {closure}(),/Applications/xampp/xamppfiles/htdocs/devlist/app/routes.php,18
    
    27.01.2014,15:44:29,Undefined variable: month,/Applications/xampp/xamppfiles/htdocs/devlist/app/routes.php,20
    27.01.2014,15:44:29,Undefined variable: day,/Applications/xampp/xamppfiles/htdocs/devlist/app/routes.php,21
    27.01.2014,15:44:29,Undefined variable: headline,/Applications/xampp/xamppfiles/htdocs/devlist/app/routes.php,22
    

    any option to fix this?

    opened by Blackbenji 8
  • put('/(:any)') slug only displays the file name part

    put('/(:any)') slug only displays the file name part

    Let's say I invoke Macaw using the following index.php file through cURL:

    <?php
    
    require_once __DIR__.'/Macaw/macaw.php';
    
    Macaw::put('/(:any)', function($slug) {
      echo "SLUG = " . $slug;
    });
    
    $ curl -v -i -X PUT -T "somefile" http://localhost/\~${USER}/macaw/index.php/this/is/a/test/
    

    The $slug value in the put route is 'somefile' and not 'this/is/a/test/somefile' as expected. Why?

    bug 
    opened by opatry 5
  • Hi, I've some problem for routing

    Hi, I've some problem for routing

    My Folder is -Controller ---Demo.php -vendor -.htaccess -index.php

    My localhost url: http://localhost/test/macaw/

    /------My .htaccess file----- RewriteEngine On RewriteBase /test/macaw/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?$1 [QSA,L]

    -------/

    My index.php file and my demo.php file like yours readme file (https://github.com/noahbuscher/Macaw/#example-passing-to-a-controller-instead-of-a-closure)

    But I see 404 on my page. Can you see where i make mistakes? Thank you.

    opened by mcyumustutan 4
  • Fix issue #74 to allow both original routing method and new maps function to co-exist

    Fix issue #74 to allow both original routing method and new maps function to co-exist

    This is a fix for issue #74 that will allow both the original method of adding routes and the new map method to coexist without throwing an error.

    Before the fix, using:

    Macaw::get('/api/pages/partial/(:num)', 'Mynamespace\API\Pages@getPartial'); Macaw::put('/api/pages/partial/(:num)', 'Mynamespace\API\Pages@updatePartial');

    would throw an error with when it tried to evaluate the maps array (which is null if you are not using the map function).

    Now it will check to see if the current element of the maps array is not null before trying to evaluate the in_array statement which avoids the error but maintains all the functionality.

    opened by SteveHawes 3
  • Error when using same route with different methods

    Error when using same route with different methods

    My route.php file contains:

    Macaw::post('/api/pages/partials', 'EWS\API\Pages@getPartials'); Macaw::get('/api/pages/partial/(:num)', 'EWS\API\Pages@getPartial');

    If I make a call to the API using /api/pages/partial/3 using the method GET everything works fine - so far so good.

    If I now update the route file to contain:

    Macaw::post('/api/pages/partials', 'EWS\API\Pages@getPartials'); Macaw::get('/api/pages/partial/(:num)', 'EWS\API\Pages@getPartial'); Macaw::put('/api/pages/partial/(:num)', 'EWS\API\Pages@updatePartial');

    and again make the call to /api/pages/partial/3 using the method GET I get the error:

    "Warning: in_array() expects parameter 2 to be array, null given in vendor/noahbuscher/macaw/Macaw.php on line 117"

    Debugging the PHP shows that the call is matched as expected (and the getPartial routine is run) but it then continues to try and match the routes and when it gets to the put version the self::maps[$pos] is null so the error is thrown.

    How can I have two identical routes but for different methods without this error occurring?

    Thanks

    opened by SteveHawes 3
  • Find 404 error in the test

    Find 404 error in the test

    Find this line of code in “ PHP - s ” 404 error occurs

    Original code

    $uri = dirname($_SERVER['PHP_SELF']).'/'.$params[0]; //29
    

    Modify code

    $uri = strpos($params[0], '/') === 0 ? $params[0] : '/' . $params[0]; //29
    
    opened by qman19791123 3
  • Compilation failed

    Compilation failed

    Warning: preg_match(): Compilation failed: unmatched parentheses at offset 15 in D:\Work\www\routine\vendor\noahbuscher\macaw\Macaw.php on line 117
    

    How to fix it?

    opened by huangzhhui 3
  • codingbean -> noahbuscher

    codingbean -> noahbuscher

    You forgot to change namespace codingbean for noahbuscher in Packagist, so you can`t just install macaw using composer rule: "noahbuscher/macaw": "dev-master"

    opened by uavn 3
  • Addition of some functions

    Addition of some functions

    1.Add routing group

    we can adopt this method.

    route::group('admin', [route::any('/index', 'app\admin@index'),
    route::any('/settings', 'app\admin@settings')]);
    

    and then you can visit the link such as ‘admin/index’ and ‘admin/settings’

    2.Added support for multi-level directory

    sometimes,we may work in the multi-level directory instead of root. therefore,We need the multi-level directory function, if not, set $app to null

    opened by dyedd 0
  • Call static doesn't check the method is correct

    Call static doesn't check the method is correct

    get, post, any are allowed methods, still if you do Macaw::lol(); it will work without complaining and you might get strange behaviors.

    So if you miss one character, like Macaw::ge() it will call successfully and add an empty route.

    opened by ppazos 0
  • $maps array is always empty

    $maps array is always empty

    It seems there should be a function map() that when called statically adds items to $maps, but that is not documented. So not sure $maps is even used for something. Can it be removed?

    opened by ppazos 0
  • Behavior of halts=false is not documented

    Behavior of halts=false is not documented

    There is the halts option in Macaw that for default is false. That means that even if a match is found, Macaw continues trying to match the current uri with other routes.

    That makes me wonder, what happens if another route matches and the controller@action for the first match was already executed and provides some output? The second controller@action is also executed and provides output?

    Looking at the code seems that $halts should be always true for a correct behavior.

    opened by ppazos 0
Owner
Noah Buscher
Noah Buscher
A lightweight and simple object oriented PHP Router

bramus/router A lightweight and simple object oriented PHP Router. Built by Bram(us) Van Damme (https://www.bram.us) and Contributors Features Support

Bramus! 935 Jan 1, 2023
Flight routing is a simple, fast PHP router that is easy to get integrated with other routers.

The PHP HTTP Flight Router divineniiquaye/flight-routing is a HTTP router for PHP 7.1+ based on PSR-7 and PSR-15 with support for annotations, created

Divine Niiquaye Ibok 16 Nov 1, 2022
Simple, fast and yet powerful PHP router that is easy to get integrated and in any project.

Simple, fast and yet powerful PHP router that is easy to get integrated and in any project. Heavily inspired by the way Laravel handles routing, with both simplicity and expand-ability in mind.

Simon Sessingø 472 Jan 4, 2023
A simple PHP Router

Panda Router Description the panda-router is a small alternative PHP router that can be used for small projects. With this router you can use differen

Jan Behrens 1 Dec 27, 2021
The simple PHP router

Macaw Macaw is a simple, open source PHP router. It's super small (~150 LOC), fast, and has some great annotated source code. This class allows you to

Noah Buscher 895 Dec 21, 2022
klein.php is a fast & flexible router for PHP 5.3+

Klein.php klein.php is a fast & flexible router for PHP 5.3+ Flexible regular expression routing (inspired by Sinatra) A set of boilerplate methods fo

null 2.6k Jan 7, 2023
Fast request router for PHP

FastRoute - Fast request router for PHP This library provides a fast implementation of a regular expression based router. Blog post explaining how the

Nikita Popov 4.7k Dec 23, 2022
Pux is a fast PHP Router and includes out-of-box controller tools

Pux Pux is a faster PHP router, it also includes out-of-box controller helpers. 2.0.x Branch Build Status (This branch is under development) Benchmark

Yo-An Lin 1.3k Dec 21, 2022
A web router implementation for PHP.

Aura.Router Powerful, flexible web routing for PSR-7 requests. Installation and Autoloading This package is installable and PSR-4 autoloadable via Com

Aura for PHP 469 Jan 1, 2023
:tada: Release 2.0 is released! Very fast HTTP router for PHP 7.1+ (incl. PHP8 with attributes) based on PSR-7 and PSR-15 with support for annotations and OpenApi (Swagger)

HTTP router for PHP 7.1+ (incl. PHP 8 with attributes) based on PSR-7 and PSR-15 with support for annotations and OpenApi (Swagger) Installation compo

Sunrise // PHP 151 Jan 5, 2023
Toro is a PHP router for developing RESTful web applications and APIs.

Toro Toro is a PHP router for developing RESTful web applications and APIs. It is designed for minimalists who want to get work done. Quick Links Offi

Kunal Anand 1.2k Dec 27, 2022
PhpRouter is a powerful, lightweight, and very fast HTTP URL router for PHP projects.

PhpRouter PhpRouter is a powerful, lightweight, and very fast HTTP URL router for PHP projects. Some of the provided features: Route parameters Predef

Milad Rahimi 152 Dec 28, 2022
A lightweight and fast router for PHP

Piko Router A lightweight and blazing fast router (see benchmarks) using a radix trie to store dynamic routes. This router maps routes to user defined

Piko framework 62 Dec 27, 2022
Thruway - an open source client and router implementation of WAMP (Web Application Messaging Protocol), for PHP.

PHP Client and Router Library for Autobahn and WAMP (Web Application Messaging Protocol) for Real-Time Application Messaging

Voryx 661 Nov 14, 2022
PHPRouter is an easy-to-use, fast, and flexible PHP router package with express-style routing.

PHP-Router is a modern, fast, and adaptable composer package that provides express-style routing in PHP without a framework.

Ayodeji O. 4 Oct 20, 2022
A lightweight and very basic PHP router.

Katya A lightweight PHP router Configuration Para servidor Apache, en el directorio del proyecto crea y edita un archivo .htaccess con lo siguiente: <

Luis Rodríguez 0 Apr 4, 2022
A PHP Router Package

Router A PHP Router Package Basic Concepts A router package is a utility that, once all http requests are redirected to an entry point, can configure

null 0 Aug 26, 2022
A fast & flexible router

Klein.php klein.php is a fast & flexible router for PHP 5.3+ Flexible regular expression routing (inspired by Sinatra) A set of boilerplate methods fo

null 2.6k Dec 28, 2022
A router for Amp's HTTP Server.

http-server-router This package provides a routing RequestHandler for Amp's HTTP server based on the request URI and method based on FastRoute. Instal

AMPHP 34 Dec 19, 2022