Home > Software engineering >  Set environment variable in .htaccess when the URL starts with directory
Set environment variable in .htaccess when the URL starts with directory

Time:09-08

I'm trying to set an environment variable in my .htaccess based on the 1st subdirectory of a URL. As long as the URL contains dira as the 1st subdirectory, it should set my variable (myvar) to a value of 123. For example, these URLs should work:

test.com/dira
test.com/dira/
test.com/dira/b
test.com/dira/b/
test.com/dira/b/random.html
test.com/dira/b/2
test.com/dira/b/2/
test.com/dira/b/2/and-so-in-into-infinity

Any other URL should be ignored, like these:

test.com
test.com/
test.com/dirb
test.com/dirc/123/456/789/blah
test.com/123/dira/
test.com/dirz/

I've tried all these rules in my .htaccess without success:

RewriteRule ^dira(.*)$ [E=myvar:123]
RewriteRule ^dira/(.*)$ [E=myvar:123]
RewriteRule ^dira/? [E=myvar:123]
RewriteRule ^dira/?$ [E=myvar:123]

In every case, myvar isn't set. So my question is, what's the syntax to wildcard everything after the first sub-directory? Thanks.

CodePudding user response:

RewriteRule ^dira(.*)$ [E=myvar:123]
RewriteRule ^dira/(.*)$ [E=myvar:123]
RewriteRule ^dira/? [E=myvar:123]
RewriteRule ^dira/?$ [E=myvar:123]

You are missing the substitution string (2nd argument) so none of these directives are actually setting an environment variable. [E=myvar:123] is seen as the substitution string (2nd argument), so would result in a rather malformed internal rewrite.

It should read something like this:

RewriteRule ^dira($|/) - [E=myvar:123]

Note the single hyphen (-) as the substitution string (2nd argument) indicating "no substitution".

The regex ^dira($|/) matches any URL-path that contains dira as the first complete path segment. eg. It matches dira, dira/ and dira/anything, but not dirasomething.

However, there are additional "problems" resulting from other directives in your .htaccess file...

RewriteRule ^([^/\.] )/?$ index.php?acid={ENV:myvar} [L]

(Aside: That should be %{ENV:myvar} - you are missing the % prefix.)

If that is the only other rule you have in your .htaccess file then the myvar env var should now be successfully set when requesting /dira/something, but not /dira or /dira/. (Because both /dira and /dira/ are internally rewritten by the above rule.)

The reason being, when matched, the above RewriteRule triggers a second pass of the rewrite engine (when used in .htaccess). This second pass causes any environment variables that are already set to be renamed with a REDIRECT_ prefix. ie. myvar becomes REDIRECT_myvar. myvar is not (re)set on the second pass because index.php does not match your rule.

You can either:

  • Modify the above RewriteRule directive (that internally rewrites the request) to prevent a second pass of the rewrite engine. This can be done by changing the L flag to END (requires Apache 2.4). For example:

    RewriteRule ^([^/.] )/?$ index.php?acid=%{ENV:myvar} [END]
    

    Note that I corrected the env var reference by including the % prefix. And there is no need to backslash-escape literal dots when used inside a regex character class.

    However, you will need to be mindful of future rules you add in order to prevent loops by the rewrite engine. And sometimes the looping nature of the rewrite engine can be desirable.

OR

  • Check for both myvar and REDIRECT_myvar in your PHP code (ie. $_SERVER['REDIRECT_myvar']). Since not all requests that start dira are rewritten by the above rule, you'll have either myvar or REDIRECT_myvar set at different times. Specifically, /dira and /dira/ will result in REDIRECT_myvar being set and /dira/something will have the expected myvar set (since it's not rewritten).
  • Related