15

I've written my own MVC framework in PHP, which uses urls in the format of:

/controller/method/param1/param2/param...

I've made it so that "default" methods can be ignored (by default index()), so this results in URLs like /controller//param1/param2/param.... For example, a URL of: /view//panel-glide/3 will call index('panel-glide', 3) in the view controller.

This works fine and dandy, but I'm concerned that search engines or some older browsers might freak out when they see the double slashes, as I don't think I've actually seem them ever be used before.

Is anyone aware of any issues I might come across by using this?

wyqydsyq
  • 1,992
  • 1
  • 20
  • 28
  • 1
    Just a side note: why not enforce a rigid structure of controller/method?param1=value1&param2=value2...? Seems much more RPC-like to me. – Lior Cohen Jun 29 '12 at 04:52
  • 1
    @LiorCohen Drupal for instance accepts a format like you suggest but rewrites the url to the OP's format. It's possible he just omitted that that is being done behind the scenes. – Jake Jun 29 '12 at 04:54
  • My primary concern is flexibility rather than strict structural enforcements. And query string parameters are still accessible with my input class (e.g. `$this->input->get('param`')` would return `value1`). I want to allow URI segments to be parsed as method parameters (like in CodeIgniter) for ease of use and nicer urls (like `/blog/post/hello-world-foo-bar-baz`) – wyqydsyq Jun 29 '12 at 04:56
  • 1
    Search engine issue: Apache Solr's JSON parser cannot handle a double slash; their extension adding comments to JSON grammar is broken and the slashes will comment out the closing quote of a string – Potatoswatter Jun 29 '12 at 05:03
  • 1
    @Potatoswatter I think you should post that as an answer. – Jake Jun 29 '12 at 05:07
  • @pyrokinetiq Using double-slashes as you're doing is perfectly ok according to the multiple URL and URI standards. BUT, using two slashes where only was meant is a very common error, so there are a lot of applications that normalize multiple contiguous slashes in path to just one slash. This **will cause errors for you too**. For example, a lot of crawlers will fail to crawl your site correctly, since normalizing multiple slashes is a very common practice. – smola Jan 05 '14 at 10:42

2 Answers2

17

There is an existing answer on WebMasters that discusses the dangers of having two slashes. It discusses Apache a lot, but the ideas should be applicable generally.

In essence, I don't think it is recommended. /foo/bar and /foo//bar really should be two completely different paths. Each slash is significant, and attempts at circumventing that standardization are bound to come back to bite you.

As is mentioned in the answer, there's also a very real danger of relative paths failing. Some browsers will correctly figure that a relative path ../../fizz from /foo/bar//baz is /foo/bar/fizz, while others will treat the double slash as a single one, and opt for /foo/fizz.

Plus, I think it looks funny.

Community
  • 1
  • 1
voithos
  • 68,482
  • 12
  • 101
  • 116
  • I agree. As a developer it looks funny. As a user it looks funny. Actually, if I bookmarked that url and the link was broken, I would expect removing the extra / to fix it. And tbh, a change in the code might make that happen. – Jake Jun 29 '12 at 04:57
  • @nomaD Just rewrite the extra / out of there. – Jake Jun 29 '12 at 04:58
  • 3
    In my case `/foo/bar` and `/foo//bar` ARE two completely different paths. `/foo/bar` will be loading the `bar()` method/action of the `foo` controller, `/foo//bar` will be loading `index('bar')` of the `foo` controller. – wyqydsyq Jun 29 '12 at 04:58
  • I agree. A user typing a URL like that is likely to feel confused. – kad81 Jun 29 '12 at 04:58
  • 2
    @nomaD: There's more to it than just aesthetics. See my edit. Is there a reason why you don't want to make the `/foo/index` an explicit URL? – voithos Jun 29 '12 at 05:03
  • Ah that's the sort of answer I was looking for, I wanted to know if there's any actual issues with my implementation rather than whether or now it would work (which it does) :). And `/foo/index` is an explicit URL, I just thought being able to exclude `/index` would be a lot nicer aesthetically, so you could load the default method (`index()`) of `foo` by simply going to `/foo`. – wyqydsyq Jun 29 '12 at 05:11
  • @nomaD: If your routing engine is clever enough, there's also the option of having `/foo` call the default `index()` method on the `foo` controller, and then for more complex URLs, like `/foo/bar/baz`, it would first try to find a `bar()` method and, only when that fails, it will try to call the `index()` method using `bar` and `baz` as arguments. Makes it a bit more complex, and there's probably a slight performance tradeoff, but might achieve what you're describing. Of course, there's also the danger of `bar` being both a method _and_ an argument to `index()` at different times... – voithos Jun 29 '12 at 05:16
  • 1
    @nomaD: So, actually, you might _not_ want to try that. :] – voithos Jun 29 '12 at 05:17
3

Apache treats multiple slashes as a single slash. This affects things such as RewriteRules, e.g. if you have a rule like this:

RewriteRule ^user/(.*)/([0-9]+)$ /user.php?id=$2 [QSA,L]

That will catch links such as user/nomaD/500 but it will not catch user//500 since it treats that as user/500

So in other words, I don't think your setup will work since it will treat param1 as method and shift all the parameters left, unless they are of a specific type. I guess this doesn't affect your specific case, but in a lot of situations, this would be a downside to using //.

andrewtweber
  • 24,520
  • 22
  • 88
  • 110
  • 1
    But he said it did work. I guess he could not be on apache and you both be right. – Jake Jun 29 '12 at 05:00
  • My setup does work, I'm using a catch-all rewrite: `RewriteRule ^(.*)$ index.php?$1 [L]`, then using PHP to parse the url and figure out what to be loading – wyqydsyq Jun 29 '12 at 05:01
  • 2
    Maybe he is breaking apart the `REQUEST_URI` to separate the parameters out then – andrewtweber Jun 29 '12 at 05:01
  • 1
    A brilliant insight. Makes good sense though. PHP doesn't care what apache thinks about double slashes. – Jake Jun 29 '12 at 05:03
  • 1
    Yep, I'm using PHP to explode the URL by `'/'`, `$segment[0]` is the controller to load, `segment[1]` is the method/action (and `if ($segment[1] == '') $segment[1] = 'index';`, and all following segments are used as parameters for the method. So `/blog//first-post` would essentially run `$framework->blog->index('first-post')` and `/blog/first-post` would run `$framework->blog->first-post()` which wouldn't exactly work ;) – wyqydsyq Jun 29 '12 at 05:08