

Toro - a php micro-router with great examples - jasonmoo
https://github.com/anandkunal/ToroPHP

======
mcfunley
How is this not just a slower .htaccess implementation with OOP boilerplate?
The instructions even mention editing .htaccess, so it's not like this is
necessarily intended for people who don't have control of it.

RewriteRule ^foo/([0-9]+)/bar /foo/bar.php?x=$1 [L,NC,QSA]

Done.

These things come across as monkey-see-monkey-do. Other frameworks in other
languages have routers, therefore they must also make sense in PHP.

~~~
jakejake
There's always the argument of abstraction vs simplicity. I appreciate both
and I didn't used to like using routers. But I do use it these days for most
of my work.

Apps often don't have a physical URL that you could map to in .htaccess like
/foo/bar.php. There's only index.php and the appropriate controller/method is
executed based on the URL. Of course you could just map .htaccess to something
like /index.php?method=foobar instead. But then you're still dealing with a
router in your index.php, perhaps a simple switch statement or something. It
wouldn't bother me to see this kind of setup but I think having a router is
just a bit cleaner.

You can also abstract retrieving values from the URL like /account/1234
(obtaining "1234") so that the router does all the parsing and the controller
isn't aware of the URL implementation. Perhaps useful for altering URLs later
without affecting the controller code. Keeping things separate also can make
unit testing somewhat easier as you can substitute the router with a mock
object and get your controller to respond to all the variations of user input.

~~~
Ralith
> There's always the argument of abstraction vs simplicity.

This is a false dichotomy. A good abstraction makes things simpler.

~~~
jakejake
You're talking about abstraction in general and I'm talking about a specific
implementation.

------
mmcnickle
Well done! This has a really clean interface, I wish I'd come across it when
looking for a simple router a few weeks ago. A lot of the other ones lean
heavily towards a style associated with their related framework, or are too
esoteric/basic.

There are a few things I would have to add before I would use it however, and
I hope they make it in some day:

1) You should add a whitelist for the HTTP request method names, i.e only
allow calls to get(), post(), not some_suspicious_call_from_bad_user(). People
will often put non HTTP methods in their views (view as in django sense) and
you don't want them to be able to be called by a malicious user.

2) You should make it easy for the developer to configure their own xhr
headers.

3) Nitpick: You should probably use 405 (Method Not Allowed) instead of 404
for when a method handler isn't found.

Maybe I'll use it in this project, in which case you may have a few pull
requests headed your way!

~~~
jasonmoo
Wow fantastic code review! I'm a minor contributor on this project and those
changes sound great.

------
citricsquid
Related: A similar project (a simple php router) called Klein exists
(<https://github.com/chriso/klein.php>) which is really great. Does anyone
have experience with both and can explain which is better?

~~~
ChiperSoft
I love Klein, but this looks WAY easier to work with and much more specific.
Klein includes a bunch of stuff for request and response handling, output
buffers and views and stuff. Toro appears to completely leave all that to the
implementer, which is very nice if you've already got code to handle those
things.

------
solox3
Reminds me of many things; as usual, the weakest part of this PHP router is
the .htaccess file.

~~~
andypants
I don't think you can do this kind of url routing in php without modifying the
.htaccess file.

~~~
Karunamon
And so it's permanently married to Apache. Too bad.. is there anything like
this that'll run on nginx/lighttpd?

~~~
tlack
All of these routers work under Nginx or Lighttpd, they just need a different
config file. Here's one that is often used under Nginx:

    
    
        location {
            root   /usr/share/nginx/html;
            index  index.php index.html index.htm;
            try_files $uri $uri/ /index.php?$request_uri;
        }

------
memnips
I've used Toro for about six months. It's excellent.

~~~
jasonmoo
Yeah me too. It's been a great tool for me as well.

------
brito
Simple, elegant solution to a typical problem where everybody else ends up
building a broken wheel.

~~~
gee_totes
Agreed. This may have replaced Sinatra for my go-to for building quickie Rest
APIs

~~~
christensen_emc
have you tried SlimPHP? I've been using it for APIs lately and its been great.
Very easy to get up and going very quickly.

------
flyosity
Looks similar to Fat Free Framework for PHP, which I've been using for a few
months. <http://bcosca.github.com/fatfree/>

------
desfrenes
Like everybody else, I wrote my own router which somehow began to grow and
became a so-called microframework: <http://azuki.desfrenes.com/>

This is probably what I would use for PHP, but obviously other languages have
better solutions like ruby/sinatra, python/flask etc.

------
jasonmoo
The toro mascot on the main site is pretty cool. <http://toroweb.org/>

------
iguana
It's an interesting approach. I use SlimPHP, which approaches the RESTful API
problem as a DSL, much like Sinatra. Slim has a few nice features, and my new
preferred PHP stack is Slim Framework + Zend Framework as a library.

------
devgutt
How can I bypass images or specific files using ToroPhp? I usually add this
lines at my _.htaccess_ :

    
    
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d

~~~
sjs382
You do just that. When setting your .htaccess to route all URLs through Toro,
use a snippet like:

RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond
%{REQUEST_FILENAME} !-d RewriteRule . /index.php

------
jmtucu
I used Moor for several projects and works like charms and it's very easy to
use ( <https://github.com/jeffturcotte/moor> )

------
sjs382
Similar to GluePHP: <http://gluephp.com/documentation.html>

------
rickmb
This illustrates exactly why PHP projects often become such an unmaintainable
mess and security hole. This looks like an example collection of PHP worst
practices.

I mean, what could possibly go wrong with untestable code and unfiltered
input...?

~~~
jasonmoo
Not sure how adding some input filtering and tests would make this an
unmaintainable mess..?

The code is actually pretty tight and is optimized for empowering a developer
rather than inflating the bumpers of your bowling lane.

------
jaequery
i wish zend framework's router was this easy

------
slurgfest
Looks clean. Way to ship!

------
gtevelde
i love it

------
mootothemax
Is this a parody of how not to do things? I was prepared to take it on face
value of being rather misguided, but thinking about it... It's a glorified
mess of goto statements and objects being misused.

I confess that I stopped digging further after I saw files being included in
methods, absolutely one of the biggest sins in PHP:

[https://github.com/anandkunal/ToroPHP/blob/master/examples/b...](https://github.com/anandkunal/ToroPHP/blob/master/examples/blog/handlers/article_handler.php)

[https://github.com/anandkunal/ToroPHP/blob/master/examples/b...](https://github.com/anandkunal/ToroPHP/blob/master/examples/blog/handlers/articles_handler.php)

~~~
lux
Not that I've looked at it in much depth, but those just look like simplistic
examples to show how the routing works. If it's just a router, then how you
render views is beyond the scope of the library, and cutting corners in
examples for the sake of expediency doesn't seem so bad.

~~~
mootothemax
_Not that I've looked at it in much depth, but those just look like simplistic
examples to show how the routing works. If it's just a router, then how you
render views is beyond the scope of the library, and cutting corners in
examples for the sake of expediency doesn't seem so bad._

I'm fine with the idea of a router simply being a router; I really take
exception to yet more PHP examples illustrating bad coding habits being on the
web though.

~~~
lux
I can agree with that. Even just changing it from

include("views/articles.php");

to

return view ('articles');

would be better...

