Search code examples
php.htaccessget

Using a $_GET variable for search function with .htaccess rules rewriting the URL variable


I am having issues searching for multiple words on my site.

My search function uses a $_GET variable for the search like so:

$term = $_GET['search'];
$newterm = '%'.$term.'%';

$params = [$newterm];
$sql = "SELECT * FROM products WHERE product_name LIKE ?";
$stmt = DB::run($sql,$params);

I also have a line in my .htaccess file which rewrites the URL from something like search.php?search=search%20term to search/search%20term like so:

RewriteRule ^search/([0-9a-zA-Z-]+)/?$ search.php?search=$1 [L,NC,QSA]

This works fine when searching for one word (e.g. 'search' or 'term') but not when searching for multiple words (e.g. 'search term').

When I do this I get a 404 error stating:

The requested URL example.com/search/search term.php was not found on this server.

The URL, however, does show the %20 in the address bar instead of the space and no .php extension, like so:

example.com/search/search%20term

It seems to be thinking this is another directory/file rather than a variable in the URL which may be caused by this line in my .htaccess file:

RewriteRule ^([^\.]+)$ $1.php [L,NC,QSA]

Edit

My full .htaccess file:

Options -MultiViews
RewriteEngine on

RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] 

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]

RewriteRule ^category/([0-9a-zA-Z-]+)/?$ category.php?id=$1 [L,NC,QSA]
RewriteRule ^product/([0-9a-zA-Z-]+)/?$ product.php?id=$1 [L,NC,QSA]
RewriteRule ^product/([0-9a-zA-Z-]+)/added?$ product.php?id=$1&added=added [L,NC,QSA]
RewriteRule ^page/([0-9a-zA-Z-]+)/?$ page.php?page_id=$1 [L,NC,QSA]
RewriteRule ^order/([0-9a-zA-Z-]+)/?$ order.php?id=$1 [L,NC,QSA]
RewriteRule ^search/([0-9a-zA-Z-]+)/?$ search.php?search=$1 [L,NC,QSA]

RewriteCond %{REQUEST_URI} ^/search/.*$ [NC]
RewriteRule ^([^\.]+)$ $1.php [L,NC,QSA]

Solution

  • To stop the search term getting matched by the second RewriteRule you showed, try putting this line before it:

    RewriteCond %{REQUEST_URI} !^/search/.*$ [NC]
    

    This will effectively ignore the /search path when processing that rule.

    Note, if you have more rules after this that conflict, you may want to move your search RewriteRule higher up in the file instead.

    Also, your regex to match the search term needs to allow for spaces too. Try this:

    RewriteRule ^search/([0-9a-zA-Z\s-]+)/?$ search.php?search=$1 [L,NC,QSA]
    

    (Note the \s added to the character class)

    View the test.