Go Back   CodingForums.com > :: Server side development > PHP

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 10-08-2012, 06:35 AM   PM User | #1
andrew55
New Coder

 
Join Date: Mar 2012
Posts: 18
Thanks: 4
Thanked 0 Times in 0 Posts
andrew55 is an unknown quantity at this point
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..
andrew55 is offline   Reply With Quote
Old 10-08-2012, 07:10 AM   PM User | #2
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,635
Thanks: 4
Thanked 2,448 Times in 2,417 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
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.
Fou-Lu is offline   Reply With Quote
Users who have thanked Fou-Lu for this post:
andrew55 (10-08-2012)
Old 10-08-2012, 04:03 PM   PM User | #3
andrew55
New Coder

 
Join Date: Mar 2012
Posts: 18
Thanks: 4
Thanked 0 Times in 0 Posts
andrew55 is an unknown quantity at this point
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..
andrew55 is offline   Reply With Quote
Old 10-08-2012, 04:57 PM   PM User | #4
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,635
Thanks: 4
Thanked 2,448 Times in 2,417 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
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.
Fou-Lu is offline   Reply With Quote
Users who have thanked Fou-Lu for this post:
andrew55 (10-09-2012)
Old 10-08-2012, 09:17 PM   PM User | #5
andrew55
New Coder

 
Join Date: Mar 2012
Posts: 18
Thanks: 4
Thanked 0 Times in 0 Posts
andrew55 is an unknown quantity at this point
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.
andrew55 is offline   Reply With Quote
Old 10-08-2012, 11:15 PM   PM User | #6
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,635
Thanks: 4
Thanked 2,448 Times in 2,417 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
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.
Fou-Lu is offline   Reply With Quote
Users who have thanked Fou-Lu for this post:
andrew55 (10-09-2012)
Old 10-09-2012, 12:01 AM   PM User | #7
andrew55
New Coder

 
Join Date: Mar 2012
Posts: 18
Thanks: 4
Thanked 0 Times in 0 Posts
andrew55 is an unknown quantity at this point
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.
andrew55 is offline   Reply With Quote
Old 10-09-2012, 02:13 AM   PM User | #8
andrew55
New Coder

 
Join Date: Mar 2012
Posts: 18
Thanks: 4
Thanked 0 Times in 0 Posts
andrew55 is an unknown quantity at this point
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.
andrew55 is offline   Reply With Quote
Old 10-09-2012, 02:23 AM   PM User | #9
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,635
Thanks: 4
Thanked 2,448 Times in 2,417 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
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.
Fou-Lu is offline   Reply With Quote
Users who have thanked Fou-Lu for this post:
andrew55 (10-09-2012)
Old 10-09-2012, 02:42 AM   PM User | #10
andrew55
New Coder

 
Join Date: Mar 2012
Posts: 18
Thanks: 4
Thanked 0 Times in 0 Posts
andrew55 is an unknown quantity at this point
thank you very much - now it's off to work to change quite a few of these
andrew55 is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 09:51 AM.


Advertisement
Log in to turn off these ads.