• PHP Help General Help
  • [RESOLVED] $_SERVER[DOCUMENT_ROOT] has mystery trailing slash added on production server

I'm working on a project with another dev. I noticed certain PHP scripts were failing on my workstation because include/require statements were neglecting to specify a trailing slash at the beginning of a path like so:

require $_SERVER["DOCUMENT_ROOT"] . "path/without/leading/slash.php";

These links were working on the dev server because the apache config there was specified with a trailing slash:

DocumentRoot "/var/www/html/"

I removed that trailing slash because the docs say The DocumentRoot should be specified without a trailing slash.

When I removed the trailing slash from the dev server's apache conf, it went away in $_SERVER["DOCUMENT_ROOT"] which made me happy because now the dev machine behaves like my workstation which is good for my sanity.

What is NOT good for my sanity is that the production server is still showing the trailing slash in _SERVRER["DOCUMENT_ROOT"] but there is no trailing slash specified in the apache conf. I've restarted apache and it's still there. I've searched my PHP code for any instance where this variable might be redefined to have a trailing slash but this returns no files:

 sudo grep -r --include=*.php --color "DOCUMENT_ROOT.*=" /var/www

What the heck? While an include of /var/www/html//some/file/path.php doesn't seem to break, I worry it might at some point. Where is this trailing slash being added? Why is it different on the production server (RHEL 6.5 Santiago) than it is on the dev server (CentOS 6.5 final) or my workstation (Ubuntu)?

    Are the Apache versions the exact same? Is PHP installed in the same way (e.g. SAPI vs. CGI)?

    I don't suspect it to differ, but if you're using the SAPI, try something like:

    var_dump( apache_getenv("DOCUMENT_ROOT", true) );
    var_dump( apache_getenv("DOCUMENT_ROOT", false) );

    to try and get a different value.

    sneakyimp;11036387 wrote:

    While an include of /var/www/html//some/file/path.php doesn't seem to break, I worry it might at some point.

    There are references out there that may or may not put your mind to ease. One example might be this one:

    Open Group Base Specifications Issue 6 wrote:

    Multiple successive slashes are considered to be the same as one slash.

      the output of php_sapi_name on both machines is apache2handler. Their PHP configurations are nearly identical. I think they might have a different setting for allow_fopen_url but that's about it.

      your code:

      var_dump( apache_getenv("DOCUMENT_ROOT", true) );
      var_dump( apache_getenv("DOCUMENT_ROOT", false) );
      

      Has different output on the servers. On the dev machine, there is no trailing slash:

      string(13) "/var/www/html"
      string(13) "/var/www/html"

      on the production server, the trailing slash is there:

      string(14) "/var/www/html/"
      string(14) "/var/www/html/"
      

      It's maddening.

      I appreciate the spec document, but don't really know what that document is. What is its significance?

        Are the dev and prod httpd.conf files identical? Have you checked any additional config files, e.g. included configs for virtual hosts in case they might overwrite default? Did you remember to restart production?

        While it would not tell you why or how, you could strip the trailing slash in php

        $_SERVER['DOCUMENT_ROOT'] = preg_replace('#/$#', '', $_SERVER['DOCUMENT_ROOT']);
        

        I also recommend having a look at nginx. I find it easier to maintain than apache. Especially when it comes to location directives and rewrites.

          I wouldn't use preg_replace to strip it, instead I would use [man]rtrim[/man]

            johanafm;11036433 wrote:

            Are the dev and prod httpd.conf files identical? Have you checked any additional config files, e.g. included configs for virtual hosts in case they might overwrite default? Did you remember to restart production?

            I looked at a list of the apache conf files on conf.d and the list of files appears to be identical on both dev and prod servers. The files themselves have different sizes, usually due to comments included in one or the other. I have not completely checked every directive. These servers each only host one website so there are no other virtual hosts in effect as far as I know. As it turns out, our plan is to retire the production server in favor of a new, cheaper virtual server offered by rackspace so the production server with added slash is going away so I guess I'll just not worry about it 🙁

            johanafm;11036433 wrote:

            I also recommend having a look at nginx. I find it easier to maintain than apache. Especially when it comes to location directives and rewrites.

            I have only the most brief exposure to nginx, but have heard really good things about it. Thanks for the suggestion! Any resources for getting started would be appreciated.

              Derokorian;11036437 wrote:

              I wouldn't use preg_replace to strip it, instead I would use [man]rtrim[/man]

              Me too if I had ever remembered it exists!
              +1 🙂

              sneakyimp;11036457 wrote:

              I looked at a list of the apache conf files on conf.d and the list of files appears to be identical on both dev and prod servers. The files themselves have different sizes, usually due to comments included in one or the other. I have not completely checked every directive. … not worry about it

              If you want to check more thouroughly, use grep and diff.
              -v = inverted, i.e. remove matching lines.
              -E = extended regexp
              Ignore lines starting with whitespace followed by # or end of line. # is apache comment too isn't it?

              grep -vE '^\s*(?:#|$)' file
              

              which together with diff

              diff <(grep -vE '^\s*(?:#|$)' devhttpd.conf) <(grep -vE '^\s*(?:#|$)' prodhttpd.conf)
              

              should show you only non-comment lines that actually differ.

              sneakyimp;11036457 wrote:

              I have only the most brief exposure to nginx, but have heard really good things about it. Thanks for the suggestion! Any resources for getting started would be appreciated.

              Just start by trying it out in whatever environment you feel the most at home. Directions for getting started with building/installing nginx.
              Another resource on nginx and php-fpm, with sample config files that should get you started on configuration.
              You will also need to have a look in the manual at the server and location directives which are both part of nginx HttpCoreModule. This link takes you to the nginx wiki which informs you that it has been deprecated and presents you with a url to the (far less readable) docs. (I still prefer reading the "readable" version and then comparing notes with the up-to-date docs)

                Write a Reply...