Before answering the question itself, an important detail that can cause a lot of confusion in your tests: do not forget to set the base path!
This can be done in . htaccess, but the simplest way is to do it by html:
<!-- inclua isso no "head" do html -->
<base href="http://a_url_do_seu_site.com/" />
So, especially when working with many folders and subfolders, files with sections and subsections, one does not miss the absolute beginning of the navigation for reference of all links.
In your case, if "categories" is always the basis, you could do it:
<!-- inclua isso no "head" do html -->
<base href="http://www.meusite.com/categoria/" />
And any return of friendly urls would start with "product/page", ignoring the categories, which would be your "home", so to speak.
Getting back to your problem, this type of situation is what we call "multiple entries" when there is more than one file. php to call, instead of just an index.php. In this case . htaccess can be configured in two ways.
First Option
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?p=$1
Here nothing changes regarding the single input case, but the existing files are also called by the "user friendly" query string. To do this, just agree that the first parameter (in your case) is a folder, and the second is the file name. For example:
www.meusite.com/categoria/produtos/2
extracting the query srtring:
$qs = explode("/", ltrim($_GET['p'], "/"));
$caminho = $qs[0];
$arquivo = $qs[1].".php";
$parametro = $qs[2];
// e assim sucessivamente...
The most important thing in this method is that you understand that you need to work out a way to standardize the addresses and folder and file structure of your project. It is easier (and beneficial in many ways) to plan the project well, than to burn phosphorus with . htaccess.
Second Option (not recommend, but there is)
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ $1\.php
What changes is that you can now pass complete paths, and the last parameter (no bar) will be the name of the php file. I think it goes without saying that there are no advantages to this approach in your case, mainly because it hinders the passage of query strings.
Finally, I see something that could be changed in your pagination code, which is like this:
if(empty($_GET['page'])){
$page=1;
}
if($page >= '1'){
$page = $page;
} else {
$page= '1';
}
When would it be more interesting to do this:
$page = 1; // por padrão, page é sempre 1
$dir = "produtos"; // outro padrão, por exemplo
if (!empty($_GET['page'])) { // todo o resto só faz sentido se houver dados
$dados = explode("/", ltrim($_GET['pages'], "/"));
$dir = $dados[0];
$page = empty($dados[1]) ? 1 : $dados[1]; // só por garantia...
}
Add another condition, for the categories.
– Edilson
I recommend an htaccess with
RewriteRule (.*) index.php [QSA,L]
and let the system route the URL. This makes it easier for you to manage routes.– Papa Charlie
Implementing Router-Friendly URL
– marcusagm