I have a PHP file named as otp.php
.
When URL in the URL bar is
http://localhost/college/otp/MTA=/teacher
It should be treated as
http://localhost/college/otp.php?user=MTA=&role=teacher
For this, I created .htaccess
file in http://localhost/college/:
RewriteEngine On # Turn on the rewriting engine
RewriteRule ^otp/?$ otp.php [NC,L]
RewriteRule ^otp/[A-Za-z-]+/([A-Za-z0-9-]+)/?$ otp.php?user=$1&role=$2 [NC,L]
But, otp.php
file says:
Notice: Undefined index: role in C:wampwwwcollegeotp.php on line
11Notice: Undefined index: user in C:wampwwwcollegeotp.php on line
11
UPDATE
When URL in the URL bar is
http://localhost/college/otp/MTA/teacher
It should be treated as
http://localhost/college/otp.php?user=MTA&role=teacher
How do I solve this problem?
2
Answers
This tool might help you to write correct expressions for your RewriteRules. Maybe, this expression would give you an idea, where the problems may be:
RegEx Descriptive Graph
This link helps you to visualizes your expressions for the RewriteRule:
Then, you can write a RewriteRule, maybe something similar to:
You might want to clear your browser history, every time that you modify your
.htaccess
file.Your
RewriteRule
pattern needs a slight modification to match your example URL, since it will currently fail on the=
inMTA=
. (Although I’ve just noticed that the "update" to your question does not show a=
in the URL?) This pattern also needs to be capturing in order for the$1
to pick it up.So, the above directive should read something like:
This assumes that
=
always appears at the end of the path segment, as in your initial example (include it inside the character class if it can occur anywhere – although would be a bit confusing). TheNC
flag is probably unnecessary, unless you also need to allow mixed case versions ofotp
(unadvisable). You already allow for mixed case in your regex.UPDATE#1: It seems the second path segment is a base64 encoded string/integer. For this you will need to include digits in the regex and there could be 0, 1 or 2 trailing
=
characters. There is also no need to match a hyphen. For example:However, the other problem you seem to be experiencing (and the one which you are actually "seeing") is a conflict with MultiViews (part of mod_negotiation). This needs to be disabled for the above mod_rewrite directive to work (in fact, to do anything). If you are not enabling this in
.htaccess
then disable it by including the following at the top of your.htaccess
file:If MultiViews is enabled then when you request
otp
(where a file with the same basename exists which would also return an appropriate mime-type) mod_negotiation issues an internal subrequest forotp.php
. The problem here is that this occurs before mod_rewrite, sootp.php
ends up being called without any URL parameters.Aside:
Your code should not be generating these "undefined index" notices. Since this is essentially "user provided data", you should check for it in your script. For example:
Note that Apache does not support line-end comments, so you should remove the
# Turn on the rewriting engine
text from the first line. (Line-end comments can appear to "work", however, that is just a coincidence with how Apache directives work in general, other times they will result in a 500 internal server error.)UPDATE#2:
Yes this can be done. Although I assume that
MTA=
should appear in both places? (You haveMTA=
in the source andMTA
in the target, which would presumably corrupt the base64 encoding?) I assume you are already linking to the correct URL internally and this is only to benefit stray requests (search engines, backlinks, etc.?)You can implement an external redirect before the above rewrite, being careful not to redirect the rewritten URL and triggering a redirect loop. For example:
This is basically the reverse of the internal rewrite (that appears later in the
.htaccess
file). The condition that checks against theREDIRECT_STATUS
environment variable ensures that it only triggers for direct requests and not rewritten requests.Note that since this is an external redirect, you need to include a root-relative URL-path in the substitution argument. ie. include the
/college
subdirectory. (Or, you can use a relative substitution and set theRewriteBase
– although you’d only do this if you have several of these directives.)$1
is a backreference to theRewriteRule
pattern (ie. alwaysotp
) and%1
and%2
are backreferences to the preceding CondPattern, ie. the value of theuser
androle
URL parameters respectively.The
QSD
flag (Apache 2.4+) discards the original query string from the request.