skip to Main Content

I am attempting to redirect a URL in a very common method, however, I can not figure this out. I have read article after article and can not make any progress. I am simply trying to have a URL such as ‘domain.com/xx/xxxxxxxxxx’ redirect in php to ‘/index.php?first=xx&last=xxxxxxxxxx’. I have attempted several apache mod_rewrites and can get the URL to remain as desired in the browser, but when I look at $_SERVER[‘REQUEST_URI’] in index.php, it is not showing up as desired. Instead it is showing the URI that was entered instead of the rewrite. It is also always adding the ‘xx’ portion of the URL. So for example:

URL: domain.com/ab/1234567890
PHP: ab/1234567890
     ab/include/file.css
     ab/include/another.css

Getting: $_SERVER['REQUEST_URI'] = domain.com/ab/1234567890
Desired: $_SERVER['REQUEST_URI'] = domain.com/index.php?first=ab&last=1234567890

There is no ‘ab’ directory, and it should be looking for files like ‘include/file.css’, etc.

Here are some of the redirects I’ve tried:

 RewriteRule ^([a-zA-Z0-9/]+)$ index.php?first=$1

 RewriteCond %{QUERY_STRING} /([a-z][a-z])/([a-zA-Z0-9]+)
 RewriteRule ^/([a-z][a-z])/([a-zA-Z0-9]+)$ index.php?first=$1&last=$2 [L]

 RewriteCond   %{QUERY_STRING}           ^[a-z][a-z]/[a-zA-Z0-9]$
 RewriteRule   ^[a-z][a-z]/[a-zA-Z0-9]+$         index.php      [L,R=301]

I have tried many others and nothing I try seems to work. Perhaps it is because I am just unfamiliar with apache redirects and how this interacts with PHP. I am good at PHP, just not apache, therefore it may be a situation where I just don’t know the terms to look for…

Any help would greatly be appreacited!

UPDATE

My current apache config is:

RewriteEngine On
RewriteRule ^[a-z][a-z]/([a-z/]+.css)$ $1   [L]
RewriteRule ([a-z][a-z])/([a-zA-Z0-9]+) index.php?first=$1&second=$2    [L]

I have tried switching orders, but that doesn’t seem to make any difference. If I check the $_SERVER[‘QUERY_STRING’] variable value in PHP, it is indeed formatting it correctly for the original URL in the browser:

Browser: domain.com/ab/0123456789
$_SERVER['QUERY_STRING']: first=ab&second=0123456789

However, for all the external files that the page is requesting, those are not being redirected correctly and the PHP script is outputting the wrong values:

Browser: domain.com/ab/include/style.css
$_SERVER['QUERY_STRING']: first=ab&second=include

This should be reporting as:

$_SERVER['QUERY_STRING']: include/style.css

It appears that the first RewriteRule is not getting selected for some reason for the css files. This is also happening with js files (obviously because no rule has been set for them yet).

It also makes no difference if I use relative paths or hard paths…

RESOLUTION

After continued effort getting the apache redirects working, I had to add a specific line for each external source location (no clue why the original RegEx statement from ‘Dont Panic’ didn’t work). Here is what my .htaccess file looks like now:

# these are for the external file requests
RewriteRule [a-z][a-z]/images/([a-zA-Z0-9_.]+)$ /images/$1 [L]
RewriteRule [a-z][a-z]/styles/([a-zA-Z0-9_.]+)$ /styles/$1 [L]

# these are for the main request for the bootstrap php file
RewriteBase /  
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ([a-z][a-z])/([a-zA-Z0-9]+) index.php?first=$1&second=$2 [L]

Also of note: if you have any external files that are not created in this example (e.g. styles/non_existent.css), the last ‘RewriteRule’ above will execute and basically run the index.php file causing errors for your site. So make sure that you create (or remove references to) external files – even if they are blank!!!

Thanks for all your help ‘Dont Panic’!

2

Answers


  1. Url will always change once page changes. Ways to circumvent this is by using javascript and load url content in a div or using iframe in html to display the target page.

    Login or Signup to reply.
  2. As I understand it, these are your requirements:

    • You want to leave the originally requested URL in the browser, ie not an external, visible-to-the-visitor 301-type redirect. In other words, map the URL in the browser to something else on the filesystem, transparently.

    • The incoming request includes 2 segments which can be matched with regular expressions;

    • You want to be able to access those 2 directory elements of the request as PHP parameters;

    An Apache internal redirect will do this. The first example on the mod_rewrite examples page in the Apache docs describes this (though you probably don’t need the [PT] flag used there, which allows further handling of the mapped URI). I think the following should do what you need:

    RewriteEngine on
    RewriteRule ([a-z][a-z])/([0-9]+) index.php?first=$1&last=$2 [L]
    

    This will handle an incoming request like domain.com/ab/1234567890, and map it – transparently, invisibly – to index.php?first=ab&last=1234567890. The visitor does not see any redirect, only the original URL in their browser. You can still access the different elements of both the external request and the internal handling of it through $_SERVER:

    ...
    [QUERY_STRING] => first=ab&last=1234567890
    [REQUEST_URI] => /ab/1234567890
    [SCRIPT_NAME] => /index.php
    [PHP_SELF] => /index.php
    ...
    [argv] => Array
        (
            [0] => first=ab&last=1234567890
        )
    

    So for example you can use $_GET['first'] in your code to find ab.

    UPDATE

    To answer extra questions added in the comments – to reference your CSS/JS from index.php, the simplest and most efficient option would be to use absolute references:

    <link href="/css/some.css" rel="stylesheet">
    

    If you can’t do that, and instead want relative links to work, you could try another internal remap. Note that an external redirect (like you’ve shown in the comments) with [R=301] will be slower, as it is really is a whole new request and response.

    Assuming you have CSS files like include/file.css, where the include/ directory is in the same directory as index.php, then a relative CSS reference in index.php like:

    <link href="include/some.css" rel="stylesheet">
    

    will – with the first redirect rule above in place – actually generate a request for ab/include/some.css. To remap that to your real file, the following internal redirect rule works:

    RewriteRule ^[a-z][a-z]/([a-z/]+.css)$ $1 [L]
    

    Note that you need to be careful now that the rules don’t overlap or interfere with each other, so I’ve added [L] to both, and also added some anchors to the CSS regex.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search