0

Let's call my site:

www.example.com

and I have a PHP file like this:

www.example.com/product.php?id=50

I would like to access it by using

www.example.com/product/50

but ALSO, very important, I have several subdirectories like

www.example.com/subsite/product.php?id=50
www.example.com/subsubsite/product.php?id=50

That must become

www.example.com/subsite/product/50
www.example.com/subsubsite/product/50

How can I solve it at best with PHP and .htaccess using mod_rewrite? I banged my head with other questions like this one but to no avail.

I can't seem to find a solution that works flawlessly, taking care of all imported files like CSS, JS and PHP classes.

MrWhite
  • 43,179
  • 8
  • 60
  • 84
Alan Piralla
  • 1,216
  • 2
  • 11
  • 21

1 Answers1

1

Ok so this might not be the complete answer but should help you find your way.

You can use regex to match your desired path pattern. So for example your htaccess might look something like...

# Check if module is installed
<IfModule mod_rewrite.c>

RewriteEngine On
RewriteBase /

# Check query for matching pattern and pass id, but also append additional query strings
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\/]+\/)?product\/([0-9]+)$ /$1product.php?id=$2 [L,QSA]

# If not file or directory on server, send to 404.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /404.php [L]

</IfModule>

And what this does is...

1. Match the uri with a regex pattern

Regex: ^([^\/]+\/)?product\/([0-9]+)$

  1. ^ - Start of string.
  2. ([^\/]+\/)? - matches any directory (if exists) and stores it for reuse.
  3. product\/([0-9]+) - Your desired path e.g. product/50 and stores the number "id" for reuse.
  4. $ - End of string.

2. Pass captured directory and id to our file

Like so: /$1product.php?id=$2 [L,QSA]

  1. $1 is our directory name including the trailing slash e.g. subsubsite/
  2. $2 is our product id e.g. 50
  3. [L,QSA] The QSA flag means we can access additional query string parameters e.g. /product/50?show=all&updated=1. More about flags can be found here http://httpd.apache.org/docs/current/rewrite/flags.html#flag_qsa

3. 404 anything not matching

Like so:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /404.php [L]
  1. !-f If request is not a file
  2. !-d If request is not a directory
  3. /404.php The file used for presenting a 404 error.

Getting the id...

With the above, you can get the ID within your product.php file like so:

$id = (int)$_GET[ 'id' ];
Levi Cole
  • 3,561
  • 1
  • 21
  • 36
  • Unfortunately, this is not working, in the sense that all included files are not loaded. – Alan Piralla Aug 05 '20 at 14:16
  • @AlanPiralla try my updated answer (including `RewriteCond %{REQUEST_FILENAME} !-f` above the RewriteRule) – Levi Cole Aug 05 '20 at 14:23
  • Nice explanation. Although the 2nd rule that rewrites to `404.php` does not seem to be a requirement here? (_Aside:_ To implement a 404 "error document", you should simply use `ErrorDocument 404 /404.php` instead, which also handles the correct HTTP status.) – MrWhite Aug 07 '20 at 22:57
  • It's still not working. All included file are imported like this: `` But in the consoles all imported files give me a 404 since they are rewritten like this: `www.example.com/product/css/main.css` – Alan Piralla Aug 11 '20 at 14:35