
Macaw - A Simple PHP Router - NoahBuscher
https://github.com/Codingbean/Macaw
======
nodesocket
Probably shouldn't be "hard" coding the scheme (http). Check
$_SERVER['https']. You can make sure this fastcgi param exists with a simple
directive in nginx (fastcgi_params):

    
    
        fastcgi_param  HTTPS  $https if_not_empty;
    

Also, the 404 route, should be able to be defined as a custom function:

    
    
        Macaw::fourofour(function() {
            header($_SERVER["SERVER_PROTOCOL"] . " 404 Not Found");
            header("Status: 404 Not Found");
        });

~~~
X4
fourofour is not as semantic as notFound, or not_found xD ..

idk. this mixes up routing and api building, right? What people currently use
most to build their api (mostly afterwards) is:
[http://docs.guzzlephp.org/en/latest/](http://docs.guzzlephp.org/en/latest/)

btw. here's a nice and new php framework I've just recently found:
[http://www.cygniteframework.com/2013/07/quickstart.html](http://www.cygniteframework.com/2013/07/quickstart.html)

------
girvo
Nice. Php's community have -- with the advent of sane dependency management
through Composer, no more PEAR yay! -- move to this small composable library
style. I think it's a great thing, using Macaw (or Slim, in my case) plus your
business logic modelled as raw, SOLID, tested classes gives you an amazing API
to work with,both on the PHP side, and on the network side. I haven't needed
to use Symfony for anything new lately,though if I was building a huge app
from scratch with a larger team, Symfony is where it's at.

------
userbinator
Oh, _that_ sort of router...

For a second I thought someone had coded an IP router in PHP. Which would be a
_really_ interesting thing to see, if not particularly practical.

~~~
Pengu
pfsense is as close as it gets

------
augustohp
I like the "slim" approach on LOC, kudos to that. I would point some - IMO -
design problems:

# Static attributes and methods. Are they really needed? They are difficult to
test and predict, specially the public attributes.

# The "echo"s on routes. Since every route is a method (encapsulated by one),
this behavior could be easily avoided (easier to test and control). You are
already using callables, you can easily test (and run) matching routes to
execute any callable until a stream is given (on Respect/Rest we learned what
a powerful feature it is).

# Lack of tests. Although low LOC, there is much happening, specially on the
"dispatch" method (it would be awesome to know through tests what the
If's/Else's actually do and prevent).

# Why (as mentioned before) the error header do not provide a proper HTTP
header!? It would also be nice to provide two different error routes: one for
client errors (404: not found, forbidden) and another to server errors
(HTTP/1.1 500 Server Error).

A suggestion (we've been talking a lot on Respect/Rest) is to implement the
URI Template (RFC 6570) for matching routes and hydration of parameters
(something macaw lacks but i like using the PHP way of $_GET, $_POST and
filter_input()). With a component dealing nicely with URI Templates many
projects would benefit from it.

------
chime
If you want something with more features but still just as simple, check out:
[http://flightphp.com/](http://flightphp.com/)

I'm using it to make a JSON backend API and it works great.

~~~
citricsquid
How does flight compare with klein
([https://github.com/chriso/klein.php](https://github.com/chriso/klein.php))?

~~~
agumonkey
klein, bottle, flask .. Am I seeing things ?

~~~
X4
what do you mean?

~~~
agumonkey
Bottle and Flask are python microframework, I just wonder if Klein's name is a
reference to them.

------
phaed
[http://macaw.co/](http://macaw.co/) Oblivious or on purpose?

~~~
brickcap
The OP has another project called parrot

[https://github.com/GetParrot/Parrot](https://github.com/GetParrot/Parrot)

so I think he just likes parrots and the name is coincidence.

~~~
NoahBuscher
Yep! Macaw will be the future router of Parrot. I'm doing a rewrite.

------
vaidik
Great project. I personally prefer Python over PHP and use it a lot for most
of the web applications. But when I must use PHP in some cases, I like
frameworks like this.

For precisely this reason, I wrote a PHP router like this called Marg -
[http://github.com/vaidik/marg](http://github.com/vaidik/marg). Used it for 3
projects and I love the way I can keep things simple and sane. And that's why
I appreciate this project as well.

Great to see sane projects like these in the PHP community.

~~~
martin_
Sane PHP developers typically don't use global to avoid using objects
properly! I only mention it because it seems you haven't given PHP a fair
chance

~~~
krapp
to be fair, I've seen that idiom used quite a bit when calling database
objects. It's still terrible.

Not as bad as using extract() though. Yes i'm looking at you Wordpress.

------
pplante
this is very elegant. i haven't used php (beyond wordpress) in years, so i am
sure a lot has changed with all the frameworks which cropped up. one of the
things i miss about php was the simplicity of dropping a file into a path and
making requests directly to it, no extra dependencies required. i know a lot
of people prefer prettier urls, so why not use .htaccess file for mod_rewrite
rather than using something like macaw?

nice job on creating a really damn simple interface.

~~~
girvo
.htacess and nginx rewriting breaks down when you need to do more complex
stuff, at least if you wasn't to keep things maintainable and clean. Pushing
routing like this through to the app side gives a lot more flexibility :)

~~~
pplante
i can see why having route parsing in the code would be useful. especially
when dealing with user created urls such as "/user/pplante/profile"

------
fidz
Is there any pattern matching router in PHP? Just like Journey on Rails. It is
faster to use Patrern Matching than sequential brute force route.

~~~
jmathai
Not just a router but Epiphany[1] lets you specify a regex for routes[2]. My
favorite part though is the API module which I blogged about a while back[3].

[1] [https://github.com/jmathai/epiphany](https://github.com/jmathai/epiphany)

[2]
[https://github.com/jmathai/epiphany/blob/master/examples/reg...](https://github.com/jmathai/epiphany/blob/master/examples/regex-
route/index.php)

[3] [https://trovebox.com/blog/building-trovebox-entirely-
using-o...](https://trovebox.com/blog/building-trovebox-entirely-using-our-
api/)

~~~
fidz
It still use sequential matching[0]. What i meant is something like AST
implementation in routing algorithm, which is obviously faster than sequential
algorithm [1] [2]

[0]:
[https://github.com/jmathai/epiphany/blob/master/src/EpiRoute...](https://github.com/jmathai/epiphany/blob/master/src/EpiRoute.php#L171)

[1]: [http://en.wikipedia.org/wiki/Shunting-
yard_algorithm](http://en.wikipedia.org/wiki/Shunting-yard_algorithm)

[2]: [http://blog.bigbinary.com/2013/01/29/journey-into-rails-
rout...](http://blog.bigbinary.com/2013/01/29/journey-into-rails-routing.html)

------
y1426i
Magic methods are expensive in PHP. You might as well define those explicitly.

------
10098
It's... 87 lines of PHP?

~~~
Phil_Latio
Don't worry, I don't get it either...

------
tmzt
I don't see a composer.json in the root of the Github. Is that planned?

~~~
timmow
One problem is the library as it stands doesn't match up to composers
namespacing requirements - which some php developers have decided they don't
like and therefore are not going to support

------
whichdan
Looks like a nice alternative to using Silex if you just need routing.

------
krapp
really nice.

if I had any suggestions at all though it would be to have the 404 route
actually return the 404 header (or have a way to specify headers with routes),
and also have it handle https.

~~~
NoahBuscher
Great! I'll get to work on these. :D

~~~
X4
how about caching as a separate composer requirement, or do you think caching
should be in a higher level in the stack?

~~~
krapp
If you can send headers with routes then I suppose you could cache with them
as well. Although that could also get a bit tricky if you didn't want the
routes to enclose an entire document. The typical use cases i'm thinking of
would be a json route and an image route.

Probably, all a bare minimum viable url router should do is display some
content based on a url or fail to an error code. I would post my own
experiments with building a url router that deals with everything (because I
tried it) but the end results were objectively worse than what's already been
posted here... i've found that it helps to have the router, and whatever
process handles rendering the document as a whole (including headers and
caching) be completely separate.

------
pauletienney
Double name is double. cf : [http://macaw.co/](http://macaw.co/)

------
vayarajesh
Handy. Nice

