PHP require_once relative to variable document root - php

I'm trying to include using require_once, however, I don't always know what the file structure will be relative to the DOCUMENT_ROOT...
it could be...
/config.php or /theapp/config.php or /dev/theapp/config.php or /something_else/theapp/config.php
I COULD path back from the file like require_once('../config.php') except in some cases the files may be in a symlink directory.
Basically I'm trying to find a way where NO MATTER the circumstance, any files that call the config.php file can find it.

This is what the include_path configuration setting is for. I usually set it in the Apache config for my site, or in a local .htaccess file. Use the php_value directive.
So, basically, in your Apache config file:
php_value include_path .:/var/www/where-your-site-is
Then, from your scripts, you just use:
<?php
require_once 'conf/config.php';
require_once 'views/template.php';
?>
No matter where in your sites directory structure you are.

If you have PHP 5.3+ use this:
// My page: /dir1/dir2/welcome.php
// My include: /inc/top.php
require_once(__DIR__.'/../../top.php');
From the docs: __DIR__ is the directory of the file. If used inside an include, the directory of the included file is returned.

You can use dirname(__FILE__)
It returns the complete path of your script.
example
require_once(dirname(__FILE__).'/../config/config.php');

Came up with a pretty simple solution that works when the app is running as one unit, as well as when the core system is linked in via symlink:
Instead of:
require_once('../../../config.php');
I use:
function changeDir($up_n){
$split = explode("/",$_SERVER['SCRIPT_FILENAME']);
array_pop($split); // Remove current file name
for ($i=1; $i<=$up_n; $i++){ array_pop($split); }
return implode("/",$split);
}
require_once(changeDir(3)."/config.php");
Just pop off

Related

How to require_once in a function that is used in different directories

I need to require a file inside of a function like so:
function MyFunction(){
require_once('../../myfile.php');
//do stuff
}
This function may be used anywhere on the site so the path for the required file should not change. I tried using chdir(dirname(__FILE__)); but that changes the directory of my other files later on in the php, which is not desired.
When I am in various directories throughout the website I get an error message that the required file failed to open stream.
How can I do this?
I tend to use $_SERVER['DOCUMENT_ROOT'] for things like this. It relies on where your document root is set up in your virtual host file though.
You should use absolute paths in this case.
In your index.php you should get the location of your index.php file, that will be your reference point:
<?php
// store it in a constant, this info will not be changed anyway
define('APP_PATH',dirname(__FILE__));
//... rest of your code here
And, when you have to do a require_once for that file (let's say myfile.php is 2 directories above your index.php file):
require_once(dirname(dirname(APP_PATH)).DIRECTORY_SEPARATOR.'myfile.php');
or if myfile.php is in the same directory with index.php:
require_once(APP_PATH.DIRECTORY_SEPARATOR.'myfile.php');
Note
DIRECTORY_SEPARATOR is the PHP constant for the path delimiter (/ in any Linux, Unix, Mac, etc, or \ in Windows.
I am going to use require_once(__DIR__'/../myfile.php') this question provided a similar solution:
php require_once not working the way I want it to.. relative path issue

PHP include file in webroot from file outside webroot

I have a php file outside my webroot in which I want to include a file that is inside the webroot.
folder outside webroot
- > php file in which I want to include
webroot
- > file to include
So I have to go one directory up, but this doesnt work:
include('../webroot/file-to-include.php');
Include full path doesn't work either:
include('home/xx/xx/domains/mydomain/webroot/file-to-include.php');
How can I accomplish this?
Full path should be:
include('/home/xx/xx/domains/mydomain/webroot/file-to-include.php');
Or you should set the path like:
include(__DIR__ . '/../webroot/file-to-include.php'); // php version >= 5.3
include(dirname(__FILE__) . '/../webroot/file-to-include.php'); // php version < 5.3
Have this in a common file, shared by all your php sources outside the webroot:
<?php
define('PATH_TO_WEBROOT', '/home/xx/xx/domains/mydomain/webroot');
And then use the following to include files.
<?php
include (PATH_TO_WEBROOT.'/file-to-include.php');
If the location of your webroot changes, you will only have to change that once in your code base.
You can configure php to automatically prepend a given file to all your scripts, by setting the auto_prepend_file directive. That file could for instance contain the PATH_TO_WEBROOT constant, or require_once the file which contains it. This setting can be done on a per domain or per host basis (see the ini sections documentation).
Also, consider using the autoload feature if you are using classes extensively.
Try prepending a trailing slash to your full path, so it looks like
include('/home/xx/xx/domains/mydomain/webroot/file-to-include.php');
Otherwise, it will be interpreted as a relative path.
You could also try to change the dir into the webroot and see if this works - for debuggign purposes:
chdir("/home/xx/xx/domains/mydomain/webroot");
include "your_file.php";
I put the secured data in the file named conn.txt,
and then I used the following PHP command:
$DbInfoFile = "../conn.txt";
Fast forward to the current day (2021), an alternative method is to simply add the PHP include_path directive into your php.ini (or user.ini) to point to the includes folder, wherever it is (inside or outside the public root). This method blends the ease of changing one line of code in your project without touching the the PHP code at all. I have no idea if this works on a Windows box since I'm on CentOS.
Example: include_path = ".:/home/{acct-name}/{include-path}" (this would be one level up from public_html or whatever your public folder is called)
This blended approach allows you to simply invoke include 'file-to-include.php'; in your PHP code without going through the whole hassle of defining the root, while retaining the flexibility of changing the includes file by modifying only one line of code sitewide.
By the way, you can have multiple include locations. In that case, you can separate the two locations with a colon such as include_path = ".:/home/{acct-name}/{include-path-1}:/home/{acct-name}/{include-path-2}".
This should work
$_SERVER['DOCUMENT_ROOT']/home/xx/xx/domains/mydomain/webroot/file-to-include.php
And make sure you have access to that level.

PHP how to find application root?

I'm having problems with my include files. I don't seem to be able to figure out how to construct my URLs when I use require_once('somefile.php'). If I try to use an include file in more than one place where the directory structures are different, I get an error that the include file cannot be found.
In asp.net, to get my application root path, I can use ~/directory/file.aspx. The tild forward slash always knows that I am referencing from my website root and find the file no matter where the request comes from within my website. It always refers back to the root and looks for the file from there.
QUESTION: How can I get the root path of my site? How can I do this so I can reuse my include files from anywhere within my site? Do I have to use absolute paths in my URLs?
Thank you!
There is $_SERVER['DOCUMENT_ROOT'] that should have the root path to your web server.
Edit: If you look at most major php programs. When using the installer, you usually enter in the full path to the the application folder. The installer will just put that in a config file that is included in the entire application. One option is to use an auto prepend file to set the variable. another option is to just include_once() the config file on every page you need it. Last option I would suggest is to write you application using bootstrapping which is where you funnel all requests through one file (usually with url_rewrite). This allows you to easily set/include config variables in one spot and have them be available throughout all the scripts.
I usually store config.php file in ROOT directory, and in config.php I write:
define('ROOT_DIR', __DIR__);
And then just use ROOT_DIR constant in all other scripts.
Using $_SERVER['DOCUMENT_ROOT'] is not very good because:
It's not always matching ROOT_DIR
This variable is not available in CGI mode (e.x. if you run your scripts by CRON)
It's nice to be able to use the same code at the top of every script and know that your page will load properly, even if you are in a subdirectory. I use this, which relies on you knowing what your root directory is called (typically, 'htdocs' or 'public_html':
defined('SITEROOT') or define('SITEROOT', substr($_SERVER['DOCUMENT_ROOT'], 0, strrpos($_SERVER['DOCUMENT_ROOT'], 'public_html')) . 'public_html');
With SITEROOT defined consistently, you can then access a config file and/or page components without adapting paths on a script-by-script basis e.g. to a config file stored outside your root folder:
require_once SITEROOT . "/../config.php";
You should use the built in magic constants to find files. __FILE__ and __DIR__. If you are on PHP < 5.3 you should use dirname(__FILE__)
E.g.
require_once __DIR__.'/../../include_me.php';
$_SERVER['DOCUMENT_ROOT'] is not always guaranteed to return what you would expect.
Define it in a config file somewhere.
Assuming you're using an MVC style where everything gets routed through a single index.php then
realpath('.');
Will show you the path to the current working directory (i.e where index.php is)
So then you can define this as
define('PROJECT_ROOT', realpath('.'));
If it's not MVC and you need it to work for files in subfolders then you can just hard code it in a config file
define('PROJECT_ROOT', 'C:/wamp/www/mysite');
Then when including something you can do;
include PROJECT_ROOT . '/path/to/include.php';
You could alternativly set the base directory in your .htaccess file
SetEnv BASE_PATH C:/wamp/www/mysite/
Then in PHP you can reference it with $_SERVER['BASE_PATH']
Try this:
$_SERVER['DOCUMENT_ROOT']

How to include file from another directory

In the root (www) I have two folders.
In the first folder, "folder1", I put a file called register.php.
In the next folder, "folder2", I put files called header.php and footer.php.
I need to include the header and footer files from folder2 in the register.php file.
How can i do this? I tried to use this include ../folder2/header.php
..but it does not work
On some configurations, adding ./ (current dir) does the trick like this:
include './../folder2/header.php';
Alternatively, you can specify in terms of document root:
include $_SERVER['DOCUMENT_ROOT'] . 'folder2/header.php';
<?php include( $_SERVER['DOCUMENT_ROOT'] . 'folder2/header.php' ); ?>
include $_SERVER['DOCUMENT_ROOT'] . '/folder2/header.php';
would work from any directory of the site
it is called absolute path and it's the only reliable way to address a file
However, in real it should be something like
include $_SERVER['DOCUMENT_ROOT'] . '/cfg.php';
// some code
include $TPL_HEADER;
using a variable, previously defined in cfg.php
However, it may fail too. Because you can be just wrong about these paths
And here goes your main problem:
but it does not work
There is no such thing as "it does not work"
There is always a comprehensive error message that tells you what exactly doesn't work and what it does instead. You didn't read it yourself, and you didn't post it here to let us show you a correct path out of these error messages.
include files should generally be kept outside of the server root.
lets say your setup is;
www/website1
and
www/includes
Then you php.ini file, or .htaccess file should stipulate that
include_path=www/includes
then from any of your files, in any directory, no matter how far down the trees they go you simply do:
include 'myfile.php';
where myfile.php is at www/includes/myfile.php
Then you can stop worrying about these issues
include dirname(__FILE__).'/../folder2/header.php';
Try This it is work in my case
<?php require_once __DIR__."/../filename.php";?>
As the PHP manual states here $_SERVER['DOCUMENT_ROOT'] is "The document root directory under which the current script is executing, as defined in the server's configuration file." For this example, $_SERVER['DOCUMENT_ROOT'] will work just fine but. . . By using the new "magic constants" provided in >= PHP 5.3, we can make this code a little safer.
Put your includes in a subfolder, and use the magic constant DIR to make a reference to the included files. DIR returns the directory of the currently executing php file. By using this, you can move your folder containing all your includes anywhere you like in your directory structure, and not need to worry if your includes will still work.

Setting PHP Include Path on a per site basis?

I can set the PHP include path in the php.ini:
include_path = /path/to/site/includes/
But then other websites are affected so that is no good.
I can set the PHP include in the start of every file:
$path = '/path/to/site/includes/';
set_include_path(get_include_path() . PATH_SEPARATOR . $path);
But that seems like bad practice and clutters things up.
So I can make an include of that and then include it into every file:
include 'includes/config.php';
or
include '../includes/config.php';
This is what I'm doing right now, but the include path of config.php will change depending on what is including it.
Is there a better way? Does it matter?
If you're using apache as a webserver you can override (if you allow it) settings using .htaccess files. See the PHP manual for details.
Basically you put a file called .htaccess in your website root, which contains some PHP ini values. Provided you configured Apache to allow overrides, this site will use all values in your PHP config, + the values you specify in the .htaccess file.
Can be used only with PHP_INI_ALL and PHP_INI_PERDIR type directives
as stated in the page I linked. If you click through to the full listing, you see that the include path is a PHP_INI_ALL directive.
Erik Van Brakel gave, IMHO, one of the best answers.
More, if you're using Apache & Virtual hosts, you can set up includes directly in them. Using this method, you won't have to remember to leave php_admin commands in your .htaccess.
Use a php.ini file in website root, if your setup uses PHP as CGI (the most frequent case on shared hosts) with the same syntax as the server-wide php.ini; put it into .htaccess if you have PHP as an Apache module (do a phpinfo() if unsure):
php_value include_path "wherever"
Note that per-folder php.ini does not affects subfolders.
Why do you think append to include path is bad practice?
This code near top of root script shouldn't be that bad...
$path = '/path/to/site/includes/';
set_include_path($path . PATH_SEPARATOR . get_include_path());
IMHO the main advantage is that it's portable and compatible not only with Apache
EDIT: I saw a drawback of this method: small performance impact. see http://www.geeksengine.com/article/php-include-path.html
Depending on how your host is set up, you may be permitted to place a php.ini file in the root of your home directory with extra configuration directives.
Your application should have a config file written in PHP. Then include that with a relative page into every page in the program. That config file will have a variable for the path to the includes dir, templates dir, images dir, etc.
You can set include_path in your php.ini file too. I'm a perl guy, so I expect to be able to load includes and have include do the right thing. I have all my includes in a specific directory, which is added to include_path. I can do things like
require_once "ClassName.php";
I don't need to worry about relative paths or locations of files.
I've also written my own CustomRequire to do things like
function CustomRequire ($file) {
if(defined('MYINCLUDEPATH')) {
require_once MYINCLUDEPATH . "/$file";
} else {
require_once $file;
}
}
That way I can change how I do includes at a later date. Of course, you still need to find a way to include your include code :)

Categories