Using .htaccess to hide the location and extension of .php file

.htaccessapache-2.4mod-rewrite

I'm trying to have all requests going to //my.domain/download?id=xx (be it http or https) be processed by /path/to/my/download.php?id=xx.

I've tried all sorts of RewriteRule rules to no avail, so there's no point in me posting anything I have, but this is a WordPress install, so this shouldn't conflict with WP's existing rules, which are:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

I would very much appreciate an explanation for any provided answer. Thank you!

EDIT

I already took a look at Redirect, Change URLs or Redirect HTTP to HTTPS in Apache – Everything You Ever Wanted to Know About Mod_Rewrite Rules but Were Afraid to Ask and can't seem to even pinpoint what section would cover this situation, as all that is too general. I'm looking for help wiht this specific situation.


EDIT 2

This is the code that is failing, with a 404, even if https://htaccess.madewithlove.be/ sais it shoudl all be good:

RewriteEngine on
RewriteCond %{REQUEST_URI} !^download
RewriteRule ^download(.*)$ wp-content/themes/XXX/inc/download.php$1

EDIT 3
I was having unrelated issues. For anyone else interested, see my answer below for the rules that worked.

Best Answer

I'm trying to have all requests going to //my.domain/download?id=xx (be it http or https) be processed by /path/to/my/download.php?id=xx.

For this you probably want to internally rewrite the URL rather than externally redirect the request, as in your existing answer. An internal rewrite won't change the URL in the browser's address bar.

The directives in your existing answer can also be simplified.

Try the following instead, before the existing WordPress directives, in order to rewrite any request for /download?id=N to /path/to/my/download.php?id=N, where N is 1 or more digits.

RewriteCond %{QUERY_STRING} ^id=\d+$
RewriteRule ^download$ path/to/my/download.php [L]

\d is a shorthand character class which matches any digit. The same as [0-9]. The + quantifier matches 1 or more digits, so this will fail (404) if id= (with no value) is included in the query string. Change back to * if id= should be successful. There is no need to capture this value (ie. surround the pattern in parentheses as in ([0-9]*) since you are not using this in the substitution.

The query string, ie. id=N is copied through to the substitution by default.

There is no need to repeat the RewriteEngine On directive, since this is already part of the WordPress code block.