Search code examples
phpapache.htaccessmod-rewriteurl-rewriting

Keep question mark on $_GET with rewrite rule


So I've found this interesting question on making the question mark symbol appear on $_GET variable after using rewrite rules.

However, as much as I've tried to accomplish this myself, I didn't quite understand how it works to have the same result on my website.

Here's my rewrite rule:

RewriteRule ^(.+)$ index.php?uri=$1 [QSA,L]

This basically allows me to route users to specific places without hard coding each page on my htaccess file, so if a user goes to /about/contact page, he's actually going to index.php?uri=/about/contact.

The problem is that sometimes I WANT the question mark to be kept in $_GET. Let's say a topic title of "What's up?" then my url would search for a topic like /topic/what-s-up? and would match with what-s-up? in the database. But, right now, my $_GET variable stores just "what-s-up" (without the "?") and my database still stores "what-s-up?" (with the "?"), which would say that there's no topic with that title when there actually is.

How can I keep the question mark so /topic/what-s-up? still translates to /topic/what-s-up? in the query string?

EDIT: FULL .HTACCESS FILE FOR TEST PURPOSES

Options -Indexes

DirectoryIndex index.html index.php

RewriteEngine On

RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^(.+)$ index.php?uri=$1 [QSA,L]

Solution

  • You can change your rule to this to capture optional ? in uri parameter:

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{THE_REQUEST} \s/+([^?]*\??\S*)\sHTTP [NC]
    RewriteRule ^(.+)$ index.php?uri=%1 [QSA,L]
    

    Since we want ? also to be captured we are using RewriteCond %{THE_REQUEST} since pattern in RewriteRule only matches REQUEST_URI. Since we are capturing value from RewriteCond hence we are using %1 instead of $1 as back-reference.

    THE_REQUEST variable represents complete original request received by Apache from your browser and it doesn't get overwritten after execution of some rewrite rules. Example value of this variable is GET /index.php?id=123 HTTP/1.1