Detecting mod_rewrite using PHP

The following post is about a solution to the problem of detecting if mod_rewrite is enabled or not. I worked on a project where CS-CART was used and after it was installed, it was complaining that the mod_rewrite module was not installed. I knew that mod_rewrite was installed so I looked at the code. The code that was detecting if mod_rewrite was enabled was assuming the DNS for the domain was working fine. It was doing an HTTP request. This means that if we installed the store in a temporary environment where the hostname is fake (put in the HOSTS file for example) then it would think mod_rewrite is NOT installed or enabled.

I think I came up with a better way and here it is. I submitted it to the CS-CART staff, we'll see if they like it.

###  .htaccess

<IfModule mod_rewrite.c>

    // Tell PHP that the mod_rewrite module is ENABLED.
    SetEnv HTTP_MOD_REWRITE On

    RewriteEngine on
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    // The rest of your rewrite rules here

</IfModule>

Now, if you want to detect it properly, you can use this code:

if (function_exists('apache_get_modules')) {
  $modules = apache_get_modules();
  $mod_rewrite = in_array('mod_rewrite', $modules);
} else {
  $mod_rewrite =  getenv('HTTP_MOD_REWRITE')=='On' ? true : false ;
}

This should work for any PHP versions. The function apache_get_modules() is the best approach but this function is only available when you have PHP 4.3.2+ AND when php is installed using mod_php. Maybe there is some cases where the function is defined but will return FALSE or empty array. The document of this function is not clear and I did not perform tests under all these conditions.

If you use this, let me know how it worked for you.

Thanks

I found a similar work-around, it was to write a dummy rewrite rule in the htaccess file and to test that rule to confirm if the mod is working by using the get_headers() function.

Good info, but unfortunately

Good info, but unfortunately it didn't work for me.

The mod is enabled on my hosting, but it doesn't detect it.

The apache_get_modules has also been disabled.

are there any work-arounds for this?

A Work Around

The function apache_get_modules() is only available when the PHP is installed as a module and not as a CGI. Maybe this is why you cannot use this function. The other reason would be caused by the disable_functions directive in your php.ini which would be set by your hosting provider.

There is two workarounds. One simple involved setting an environment variable in your .htaccess inside the "IfSection" section for the rewrite rules and checking for this value in your PHP code.

Consider the following .htaccess file:

<IfModule mod_rewrite.c>

    # Tell PHP that the mod_rewrite module is ENABLED.
    SetEnv HTTP_MOD_REWRITE On

    RewriteEngine on
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule (.*) index.php?q=$1

</IfModule>

Now the index.php file
<?php

if (is_mod_rewrite_enabled()) {
  print "The apache module mod_rewrite is enabled.<br/>\n";
} else {
  print "The apache module mod_rewrite is NOT enabled.<br/>\n";
}

/**
 * Verifies if the mod_rewrite module is enabled
 *
 * @return boolean True if the module is enabled.
 */

function is_mod_rewrite_enabled() {
  if ($_SERVER['HTTP_MOD_REWRITE'] == 'On') {
    return TRUE;
  } else {
    return FALSE;
  }
}

This first workaround only works if your apache has the mod_env module enabled.

The second work around would be to perform a curl call to your own website with the url being crafted as one that would work if mod_rewrite was enabled. If the output you get back is what you expect, this means that mod_rewrite is enabled for you.
This only works if the domain of your website is working properly.
In my case, I often work on websites that are under developement and only available thru a dummy domain name. In those cases, the work around would not work.

Here is a sample .htaccess and index.php that you can put in a root of any hosting package.
If you put it in a sub folder, you will have to adjust it.

The .htaccess file:

<IfModule mod_rewrite.c>

    # Tell PHP that the mod_rewrite module is ENABLED.
    SetEnv HTTP_MOD_REWRITE On

    RewriteEngine on
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule (.*) index.php?q=$1

</IfModule>

The index.php file:

<?php
// Print the value of the "q" parameters so we can compare it in our test function below.
echo "Current URL: " . $_GET['q'] . "<br/>\n";

// Prevent infinite loops by checking if this request is done by our function
if ($_GET['q'] != 'test_mod_rewrite') {
  if (is_mod_rewrite_enabled()) {
    print "The apache module mod_rewrite is enabled.<br/>\n";
  } else {
    print "The apache module mod_rewrite is NOT enabled.<br/>\n";
  }
}

/**
 * Verifies if the mod_rewrite module is enabled by calling itself in
 * a way that will trigger the mod_rewrite rules.
 * This only works if you have an .htaccess file in the same folder
 * and if the rule will redirect anything to ?q=$1
 *
 * @return boolean True if the module is enabled.
 */

function is_mod_rewrite_enabled() {
  $content = file_get_contents("http://" . $_SERVER['HTTP_HOST'] . "/test_mod_rewrite");
  if ($content == "Current URL: test_mod_rewrite<br/>\n") {
    return TRUE;
  } else {
    return FALSE;
  }
}

The .htaccess rewrite rule will rewrite any path that do not exists to "index.php?q=whatever" where "whatever" is the path that do not exists.

The index.php simply returns the value of the "q" parameter.
To prevent infinite loop it check to see if you are viewing the path for testing if mod_rewrite is enabled.
If you are viewing any other page, it will call my function that will perform a file_get_contents() on itself but will use a path that does not exists, which will of course trigger the mod_rewrite if it is enabled and working properly. If it is working properly, the value that you will get back is then compared with the value we expect.

I hope this helps you :)

--
Christian Roy

Thanks for your quick

Thanks for your quick help.

I was already using the ifSelection, the first trick you just posted seemed to have worked for me :)

function is_mod_rewrite_enabled() {
if ($_SERVER['HTTP_MOD_REWRITE'] == 'On') {
return TRUE;
} else {
return FALSE;
}
}

@Also:

i was wondering if you can post a simple (easy) tutorial on how to make a single page (index.php) process all the request (like wordpress does), currently i have 3 pages processing index.php, cats.php and channels.php (i want to make it so that i only have to use index.php to make the request yet still get the SEO friendly URL's, i am not sure what i should for this i imagine this to be similar to the way i am doing but i don't think i get the logic behind.

Thanks again.

Front-Controller Design pattern

Sounds like you are talking about Front-Controller Design pattern (often part of MVC).

You can read tutorials about that here:

Or you can use an existing framework to build your site. Look for Symfony, CakePHP, Zend Framework, CodeIgniter.

Or you can use Drupal to build your websites.

--
Christian Roy

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <blockquote>
  • You may post PHP code. You should include <?php ?> tags.
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>. Beside the tag style "<foo>" it is also possible to use "[foo]". PHP source code can also be enclosed in <?php ... ?> or <% ... %>.
  • Web page addresses and e-mail addresses turn into links automatically.

More information about formatting options