Tags

, , , ,

I recently met a problem on an osCommerce installation when trying to move it from mod_php to FastCGI.

The culprit was the usage of SEF URLs (search engine friendly) not being properly understood under FastCGI. I did a little research into the osCommerce code and found the relevant code in application_top.php. It was using getenv('PATH_INFO'), which so happens that on that particular webhost, while under FastCGI, is not a populated variable.

What is PATH_INFO

PATH_INFO is an environment variable set by Apache to be the trailing part of the URL (in SEF-like URLs) after the actually existing script filename.

For instance a regular link may be:

http://example.com/test.php?var1=value1&var2=value2

a SEF version of that is:

http://example.com/test.php/var1/value1/var2/value2

in this case the ‘PATH_INFO’ should be: /var1/value1/var2/value2

How to find PATH_INFO

In this host, there is no PATH_INFO env and no $_SERVER[‘PATH_INFO’].

My solution:

  /* fix for PATH_INFO */
  $PATH_INFO = '';
  if (strlen(getenv('PATH_INFO')) > 1) { // false on my host
    $PATH_INFO = getenv('PATH_INFO');
  } elseif (isset($_SERVER['PATH_INFO']) && strlen($_SERVER['PATH_INFO']) > 1) { // false on my host
    $PATH_INFO = $_SERVER['PATH_INFO'];
  } elseif (isset($_SERVER["ORIG_PATH_INFO"]) && strlen($_SERVER['ORIG_PATH_INFO']) > 1) { // bingo!
    $PATH_INFO = $_SERVER['ORIG_PATH_INFO'];
  } else {
    //Failsafe / Fallback solution.
    //tests show:
    //$_SERVER["SCRIPT_NAME"] /test/path_info_test.php
    //$_SERVER["REQUEST_URI"] /test/path_info_test.php/test1/test2/test3
    $PATH_INFO = str_replace($_SERVER["SCRIPT_NAME"], '', $_SERVER["REQUEST_URI"]);
  }

…and replaced any usage of getenv('PATH_INFO') with $PATH_INFO.

Tada!

Now, this was a quick and dirty hack to get things going again, on that particular host it works OK (it goes with $_SERVER["ORIG_PATH_INFO"]). On other hosts more trickery may be needed, but the fallback solution should probably work. This all assumes all links go through osCommerce’s url changing scheme of changing ‘?’, ‘&’ and ‘=’ to ‘/’, any misbehaving code may fudge this up by adding a non-SEF parameter part at the end of the URL.

Do you think I missed anything?

Advertisements