tags:

views:

5749

answers:

9

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 different 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 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]/"?

+2  A: 

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.

Ryan Fox
+11  A: 

This should work

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

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

Edit: added imporvement by aussieviking

Peter Coulton
+3  A: 

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

I think the variable you are looking for is: $SERVER["DOCUMENTROOT"]

Christian Hagelid
On Stack Overflow, text between _ is italicized unless you put it inside a code block or between ` (inline code).
Christian Davén
+5  A: 

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.

Kevin
A: 

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

Flubba
A: 

@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.

Xenph Yan
A: 

@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.

Flubba
A: 

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.

Darryl Hein
+1  A: 

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.

Sam McAfee