Reputation: 83981
I have a directory structure like the following;
script.php
inc/include1.php
inc/include2.phpobjects/object1.php
objects/object2.phpsoap/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 programmatically generate the "/mnt/webdev/[project name]/"
?
Upvotes: 99
Views: 146529
Reputation: 139
If you are going to include specific path in most of the files in your application, create a Global variable to your root folder.
define("APPLICATION_PATH", realpath(dirname(__FILE__) . '/../app'));
or
define("APPLICATION_PATH", realpath(DIR(__FILE__) . '/../app'));
Now this Global variable "APPLICATION_PATH" can be used to include all the files instead of calling realpath() everytime you include a new file.
EX:
include(APPLICATION_PATH ."/config/config.ini";
Hope it helps ;-)
Upvotes: 0
Reputation: 13087
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.
Upvotes: 46
Reputation: 29
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');
?>
Upvotes: 2
Reputation:
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");
Upvotes: 1
Reputation: 144977
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.
Upvotes: 2
Reputation: 8355
have a look at http://au.php.net/reserved.variables
I think the variable you are looking for is: $_SERVER["DOCUMENT_ROOT"]
Upvotes: 6
Reputation: 10133
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.
Upvotes: 6
Reputation: 22875
@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.
Upvotes: 0
Reputation: 22875
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
Upvotes: 1
Reputation: 55789
This should work
$root = realpath($_SERVER["DOCUMENT_ROOT"]);
include "$root/inc/include1.php";
Edit: added imporvement by aussieviking
Upvotes: 157
Reputation: 10259
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.
Upvotes: 6