TL;DR The MultiViews option in Apache automatically will map e.g. /xfz/
to /xyz.php
I was recently creating a new section of the website I work for and decided to opt for tidy URLs, for SEO purposes, instead of our standard.long?url=format
URLs that we have elsewhere. Let’s say the new section I was creating was called David’s Boxes, so I wanted to have relative URLs like /davids-boxes/big/blue
map to davids-boxes.php?size=big&colour=blue
. Purely co-incidentally, there happened to be a defunct davids-boxes
folder in our www
directory, which contained an old WordPress install, which I prompty deleted (more on this later). Then, I set up rewrite rules in our www/.htacess
to do the example mapping above.
Everything was working fine locally: /davids-boxes/
matched to /davids-boxes.php
and /davids-boxes/big/blue
mapped to /davids-boxes.php?size=big&bolour=blue
, all as expected. However, when I put the .htaccess
file onto our test server, I couldn’t get the rules to match properly: everything mapped to the basic /davids-boxes.php
, i.e. with no extra GET parameters. I tried different order of rules, moving the rules to the top of the .htaccess
etc., but nothing worked. Then I simply deleted the rules from the .htaccess
, expecting /davids-boxes/
not to map to anything, but it still strangely mapped to /davids.boxes.php
as before. This led me to believe there was another rewrite rule somewhere else (a fact that was also helped by the previous WordPress install). Searching the entire codebase, which includes all ‘sub-‘.htaccess files, yielded no results, so then I began thinking it might be the server…
I had a look in our sites-available
Apache configs, expecting there may be some sort of obvious generic rewrite to map any e.g. /xyz/
to xyz.php
; no such luck. Going through each line in the config, I noticed we had the FollowSymLinks
and MultiViews
options enabled in the <Directory>
tag. I was familiar with the former, but not the latter. Investigating into MultiViews
, it turns out this was the thing doing the automatic mapping I was experiencing! The documentation states “if /some/dir
has MultiViews
enabled, and /some/dir/foo
does not exist, then the server reads the directory looking for files named foo.*
, and effectively fakes up a type map which names all those files”. Such relief to figure it out. I checked with our CTO, he didn’t know how it got there, so after removing it on testing and doing a quick test, we got rid of it everywhere and my problems were solved.