Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 10 of 10
  1. #1
    New Coder
    Join Date
    Mar 2012
    Posts
    18
    Thanks
    4
    Thanked 0 Times in 0 Posts

    Need help with SSI paths in php

    I just migrated to a new hosting account. Almost all of my files are in php. In my last hosting account, to create a server side include, I used something like:

    PHP Code:
    <?php 
    require_once($_SERVER['DOCUMENT_ROOT'].'/includes/header.php'); 
    ?>
    New hosting account won't seem to let me do this. Everything has to be relative such as

    PHP Code:
    <?php 
    include ("../includes/header.php"); 
    ?>
    But...this also seems to work in the new hosting account:


    PHP Code:
    <?php 
    include ("includes/header.php"); 
    ?>
    Is it OK to code all SSIs as demonstrated in the last example, or is this a bad practice. Having to set the relative paths will be much more complex and time consuming so I'm trying to avoid it. Thank you for any suggestions.
    Last edited by andrew55; 10-08-2012 at 06:38 AM.

  • #2
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,980
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    These aren't actually SSI's. These are inclusions which effectively assemble the parts from smaller parts. SSI's are interpreted during the serve, while the includes are interpreted during the request. The virtual() function can be used to create actual SSI's if for whatever reason you need them.

    I do not recommend simply using a flat path unless its taken well into control. Inclusions and requires are always based off of the executing file's working directory, regardless of the depth of the files used for including. For this reason, only your first example is the proper usable one.
    You can get around this by setting include paths (using set_include_path and get_include_path to append). This lets you search a directory for these paths and then include. It is based on order it is found.
    If you like the relative, always go relative to this file. So in that second example, it would be require_once __DIR__ . '/../includes/header.php';, or dirname(__FILE__) if you're on an older version of PHP. Unless there is a particular need for it, don't use a regular require or include, always use the _once function to avoid stomping created variables, and avoid fatal errors on already declared functions, constants, classes, etc. Prior to this, we would use a defined() check, but that is no longer necessary. Also, you'll very rarely need an actual include; mostly you are constructing out of other pieces, so these are typically required.

  • Users who have thanked Fou-Lu for this post:

    andrew55 (10-08-2012)

  • #3
    New Coder
    Join Date
    Mar 2012
    Posts
    18
    Thanks
    4
    Thanked 0 Times in 0 Posts
    Fou-Lu,

    Thank you for your thorough response. When I use the first example, I receive this error message:

    Code:
    Warning: require_once(/usr/local/apache/htdocs/includes/header.php) [function.require-once]: failed to open stream: No such file or directory in /home/mysitename/public_html/index.php on line 25
    
    Fatal error: require_once() [function.require]: Failed opening required '/usr/local/apache/htdocs/includes/header.php' (include_path='.:/usr/lib/php:/usr/local/lib/php') in /home/mysitename/public_html/index.php on line 25
    So for some reason, the "require_once($_SERVER['DOCUMENT_ROOT']" call is not working properly on my new server.

    Any ideas on how to modify this to get it working properly? You mentioned this is the proper method and I prefer it much more than using relative paths. Thank you for any suggestions.
    Last edited by andrew55; 10-08-2012 at 04:06 PM.

  • #4
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,980
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    No it sure isn't working. They've managed to do something to rewrite it. DOCUMENT_ROOT should be virtually mapped to you, but it clearly isn't:
    Code:
    /usr/local/apache/htdocs/includes/header.php
    /home/mysitename/public_html/index.php
    The DOCUMENT_ROOT should be pathed to /home/mysitename/public_html, but it has been improperly configured from the looks of it. Best to contact your host about that.

    Do the relative to this directory approach. Overall its far more useful anyways since you can use it in cron jobs while DOCUMENT_ROOT cannot be (unless you manually set it).
    PHP Code:
    require_once __DIR__ '/../includes/header.php'
    The only thing to remember is you will now always go relative to THIS file that the require is called in, not to the file that is currently executing. This does make nested includes a lot easier to work with though since you never need to concern yourself with where it is running from.

  • Users who have thanked Fou-Lu for this post:

    andrew55 (10-09-2012)

  • #5
    New Coder
    Join Date
    Mar 2012
    Posts
    18
    Thanks
    4
    Thanked 0 Times in 0 Posts
    I talked to the hosting account techs and although they are a great company, they let me know setting the document root functionality is not natively supported in their cPanel at this time.

    I have a couple thousand SS includes (or whatever they technically are) that I will have to edit in the site, and I am trying to avoid using relative paths for this reason - this seems as if will be very time consuming

    Just to make sure I understand, the following method does work when I test it, but you are suggesting that I do not use this method?


    PHP Code:
    <?php 
    include ("includes/header.php"); 
    ?>
    Thank you for any suggestions.

  • #6
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,980
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    You should never use a relative path alone since their paths are resolved to the current working directory which is always the executing script. Doing so will mean you cannot change the nesting. If you include this file in a file that's two directories below it, it will attempt to load includes off of the directory two below. Using __DIR__ resolves this as it will always be relative to this script, not the executing script.

  • Users who have thanked Fou-Lu for this post:

    andrew55 (10-09-2012)

  • #7
    New Coder
    Join Date
    Mar 2012
    Posts
    18
    Thanks
    4
    Thanked 0 Times in 0 Posts
    Upon testing, this example seems to work:

    PHP Code:
    <?php 
    require_once __DIR__ '/includes/header.php';
    ?>
    Just to confirm, would this be the correct method? My apologies for all of the questions, I'm just trying to make sure I understand this correctly.

  • #8
    New Coder
    Join Date
    Mar 2012
    Posts
    18
    Thanks
    4
    Thanked 0 Times in 0 Posts
    I think I understand..if the file is in the root, it should be:

    PHP Code:
    <?php 
    require_once __DIR__ '/includes/header.php';
    ?>
    If it's one directory deep, it should be:

    PHP Code:
    <?php 
    require_once __DIR__ '/../includes/header.php';
    ?>
    If it's two directories deep, it should be:

    PHP Code:
    <?php 
    require_once __DIR__ '/../../includes/header.php';
    ?>
    etc...

    Please confirm this is correct and thank you.

  • #9
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,980
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    By deep, you mean this file right?
    Then yep that's exactly what that is. That second one would take this file, and move up two directories to find includes/header.php. The difference in this route is (as mentioned) the use of inclusion nesting:
    Code:
    /
     - index.php
     -- includes
        - header.php
        - footer.php
     -- functions
        - generic.php
    With the above, if you were to include the generic.php within the header.php, that would be require_once '../functions/generic.php';. However, if you include header.php into index.php, then it will throw a fatal error since it cannot find /../functions/generic.php. This is why if you use a relative path you should make it relative from this file, not from an unknown working directory. By putting __DIR__ or dirname(__FILE__) on older PHP versions gets around this. Now when you include header, it will always look a directory up from the header file, not from the index file.

  • Users who have thanked Fou-Lu for this post:

    andrew55 (10-09-2012)

  • #10
    New Coder
    Join Date
    Mar 2012
    Posts
    18
    Thanks
    4
    Thanked 0 Times in 0 Posts
    thank you very much - now it's off to work to change quite a few of these


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •