How to include PHP files that require an absolute path?

0 votes
asked Aug 7, 2008 by xenph-yan

I have a directory structure like the following;

script.php

inc/include1.php
inc/include2.php

objects/object1.php
objects/object2.php

soap/soap.php

Now, I use those objects in both script.php and /soap/soap.php, I could move them, but I want the directory structure like that for a specific reason. When executing script.php the include path is inc/include.php and when executing /soap/soap.php it's ../inc, absolute paths work, /mnt/webdev/[project name]/inc/include1.php... But it's an ugly solution if I ever want to move the directory to a different location.

So is there a way to use relative paths, or a way to programically generate the "/mnt/webdev/[project name]/"?

10 Answers

0 votes
answered Aug 7, 2008 by ryan-fox

You could define a constant with the path to the root directory of your project, and then put that at the beginning of the path.

0 votes
answered Aug 7, 2008 by peter-coulton

This should work

$root = realpath($_SERVER["DOCUMENT_ROOT"]);

include "$root/inc/include1.php";

Edit: added imporvement by aussieviking

0 votes
answered Aug 7, 2008 by christian-hagelid

have a look at http://au.php.net/reserved.variables

I think the variable you are looking for is: $_SERVER["DOCUMENT_ROOT"]

0 votes
answered Aug 7, 2008 by kevin

You can use relative paths. Try __FILE__. This is a PHP constant which always returns the path/filename of the script it is in. So, in soap.php, you could do:

include dirname(__FILE__).'/../inc/include.php';

The full path and filename of the file. If used inside an include, the name of the included file is returned. Since PHP 4.0.2, __FILE__ always contains an absolute path with symlinks resolved whereas in older versions it contained relative path under some circumstances. (source)

Another solution would be to set an include path in your httpd.conf or an .htaccess file.

0 votes
answered Aug 7, 2008 by polsonby

I think the best way is to put your includes in your PHP include path. There are various ways to do this depending on your setup.

Then you can simply refer to

require_once 'inc1.php';

from inside any file regardless of where it is whether in your includes or in your web accessible files, or any level of nested subdirectories.

This allows you to have your include files outside the web server root, which is a best practice.

e.g.

site directory
    html (web root)
        your web-accessible files
    includes
        your include files

Also, check out __autoload for lazy loading of class files

http://www.google.com/search?q=setting+php+include+path

http://www.google.com/search?q=__autoload

0 votes
answered Aug 8, 2008 by polsonby

@Flubba, does this allow me to have folders inside my include directory? flat include directories give me nightmares. as the whole objects directory should be in the inc directory.

Oh yes, absolutely. So for example, we use a single layer of subfolders, generally:

require_once('library/string.class.php')

You need to be careful with relying on the include path too much in really high traffic sites, because php has to hunt through the current directory and then all the directories on the include path in order to see if your file is there and this can slow things up if you're getting hammered.

So for example if you're doing MVC, you'd put the path to your application directoy in the include path and then specify refer to things in the form

'model/user.class'
'controllers/front.php'

or whatever.

But generally speaking, it just lets you work with really short paths in your PHP that will work from anywhere and it's a lot easier to read than all that realpath document root malarkey.

The benefit of those script-based alternatives others have suggested is they work anywhere, even on shared boxes; setting the include path requires a little more thought and effort but as I mentioned lets you start using __autoload which just the coolest.

0 votes
answered Aug 9, 2008 by darryl-hein

Another option, related to Kevin's, is use __FILE__, but instead replace the php file name from within it:

<?php

$docRoot = str_replace($_SERVER['SCRIPT_NAME'], '', __FILE__);
require_once($docRoot . '/lib/include.php');

?>

I've been using this for a while. The only problem is sometimes you don't have $_SERVER['SCRIPT_NAME'], but sometimes there is another variable similar.

0 votes
answered Aug 18, 2008 by sam-mcafee

Another way to handle this that removes any need for includes at all is to use the autoload feature. Including everything your script needs "Just in Case" can impede performance. If your includes are all class or interface definitions, and you want to load them only when needed, you can overload the __autoload() function with your own code to find the appropriate class file and load it only when it's called. Here is the example from the manual:

function __autoload($class_name) {
    require_once $class_name . '.php';
}

$obj  = new MyClass1();
$obj2 = new MyClass2(); 

As long as you set your include_path variables accordingly, you never need to include a class file again.

0 votes
answered Aug 10, 2012 by thane-gill

I found this to work very well!

function findRoot() { 
    return(substr($_SERVER["SCRIPT_FILENAME"], 0, (stripos($_SERVER["SCRIPT_FILENAME"], $_SERVER["SCRIPT_NAME"])+1)));
}

Use:

<?php

function findRoot() {
    return(substr($_SERVER["SCRIPT_FILENAME"], 0, (stripos($_SERVER["SCRIPT_FILENAME"], $_SERVER["SCRIPT_NAME"])+1)));
}

include(findRoot() . 'Post.php');
$posts = getPosts(findRoot() . 'posts_content');

include(findRoot() . 'includes/head.php');

for ($i=(sizeof($posts)-1); 0 <= $i; $i--) {
    $posts[$i]->displayArticle();
}

include(findRoot() . 'includes/footer.php');

?>
0 votes
answered Aug 13, 2015 by amm0nium
require(str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1))."/path/to/file.php");

I use this line of code. It goes back to the "top" of the site tree, then goes to the file desired.

For example, let's say i have this file tree:

domain.com/aaa/index.php
domain.com/bbb/ccc/ddd/index.php
domain.com/_resources/functions.php

I can include the functions.php file from wherever i am, just by copy pasting

require(str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1))."/_resources/functions.php");

If you need to use this code many times, you may create a function that returns the str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1)) part. Then just insert this function in the first file you include. I have an "initialize.php" file that i include at the very top of each php page and which contains this function. The next time i have to include files, i in fact just use the function (named path_back):

require(path_back()."/_resources/another_php_file.php");
Welcome to Q&A, where you can ask questions and receive answers from other members of the community.
Website Online Counter

...