I have the following code (simplified) to add a path to my include paths (to temporarily fix an website with old code).
set_include_path(get_include_path() . PATH_SEPARATOR . '/foo/bar');
I have a settings file /foo/settings/settings.inc.php
Now when I have set the include path and I am in a file /foo/bar/members.php I want to include the settings file. So what the code does is:
include '../settings/settings.inc.php'
I would think that it would get that file now. But it doesn't. When I put the full path in the include it does work. eg: /foo/settings/settings.inc.php but there are a lot of files. And I thought that this would be a work around for that so I don't have to replace every file manually.
I'd say you can't do that:
Files are included based on the file path given or, if none is
given, the include_path specified. [...]
If a path is defined — whether absolute (starting with a drive letter
or \ on Windows, or / on Unix/Linux systems) or relative to the
current directory (starting with . or ..) — the include_path will be
ignored altogether.
Related
In my php project I try to include another file. However, I find it very confusing how the include statement works.
e.g.
I include the file HelperFile.php in index.php. Both files are in the same directory.
This works: include 'HelperFile.php' but this doesn't include '/HelpferFile.php' & include './HelpferFile.php'
The warning I receive:
PHP Warning include(/HelperFile.php): failed to open stream
Out of curiosity I created a folder and moved my file HelperFile.php into it and nothing changed. Everytime I tried to use the relative path with ./, ../ or /I received a warning.
Can someone explain me what's going on. I'm still learning and can'f figure out what's happening right now.
PHP isn't so great with relative paths, it generally prefers absolute paths. The easiest way around this is to use the DIR magic constant which returns the current directory of the file you're currently in.
So, for instance, you can do include(__DIR__ . '/HelperFile.php'); which would be in the current directory.
However say you had a file in a folder up you can do
include(__DIR__ . '/../MyOtherFile.php');
PHP Doc says
If a path is defined — whether absolute (starting with a drive letter
or \ on Windows, or / on Unix/Linux systems) or relative to the
current directory (starting with . or ..) — the include_path will be
ignored altogether. For example, if a filename begins with ../, the
parser will look in the parent directory to find the requested file.
If you use . or .. will ignored for relative path Also use ../ for parent directory.
Suppose i have this file:
/Home/user/docs/somewhere/inHere.php
And in this php, i want to require this:
/Home/user/other/well/buried/place.php
I know the difference between an absolute and relative path, but cannot seem to figure out how php wants this to look, i keep getting 'file not found or does not exist'
I am on a hostgator shared web server, if that has any bearing on anything.
Include it using absolute paths.
Either:
include '/Home/user/other/well/buried/place.php';
or do it relative from where you are, but still absolute:
include __DIR__ . '/../../other/well/buried/place.php';
The magic constant __DIR__ contains the absolute path to the file it was written in.
If you just do a relative path include '../../and-so-on', the starting point will change if you're including that file in some other file that resides in some other location.
Firstly you can get the current folder using getcwd().
Next, you can use $path = '../../etc'; $realPath = realpath($path). It will return false if the path is wrong, and the concrete path without relative ../'s if it is indeed an actual path.
If you still can't get it, var_dump($path); and then copy the path and try to cd into it, you should diascover what you are doing wrong at that point.
From the file location (somewhere) you have to go upwards (to docs) and another time (to user), and then go inside "other", like this:
include ("../../other/well/buried/place.php");
There you go.
I work with PHP on Windows, sience a few days. The whole time I've been indicated include in the following manner:
In index.php file:
require ('include/init.inc');
In the directory "include" I stated:
In init.inc file:
require ("workbench.inc");
But suddenly no longer works. At one time I must also in "init.inc" specify the directory.
Why did it all the time to work, and suddenly no more?
From the PHP documentation:
Files are included based on the file path given or, if none is given,
the include_path specified. If the file isn't found in the
include_path, include will finally check in the calling script's own
directory and the current working directory before failing
So the current working directory (CWD) is important when including other files. It can be retrieved by getcwd().
If your directory structure looks like this
rootdir/
include/
init.rc
workbench.rc
index.php
then a require('include/init.rc') will only work if rootdir/ is the CWD or is part of the search path. Likewise, require('init.inc') assumes the CWD is rootdir/include/. Since the current working directory can change, it is idomatic in PHP to use the more robust
// in index.php
require(__DIR__ . '/include/init.rc');
// in workbench.rc
require(__DIR__ . '/init.rc');
Then the require will work independent of the CWD. This works because the magic constant __DIR__ is replaced by the absolute path to the file that contains the constant without a trailing directory separator, for example
in index.php, __DIR__ is D:\path\to\rootdir and
in include/init.rc, __DIR__ is D:\path\to\rootdir\include.
I have a file
workers/activity/bulk_action.php which includes a file
include('../../classes/aclass.php');
Inside aclass.php it does:
include ('../tcpdf/config/lang/eng.php');
It seems that the include in the second file is using the first files working directory instead of being relative to itself, resulting in an error. How does this work?
You can adapt the second include with:
include (__DIR__.'/../tcpdf/config/lang/eng.php');
The magic constant __DIR__ refers to the current .php file, and by appending the relative path after that, will lead to the correct location.
But it only works since PHP5.3 and you would have to use the dirname(__FILE__) construct instead if you need compatibility to older setups.
You would be way better off by setting a proper value to the include_path and then use paths relative to this directory.
set_include_path(
get_include_path() .
PATH_SEPARATOR .
realpath(__DIR__ . '/your/lib')
);
include 'tcpdf/config/lang/eng.php';
include 'classes/aclass.php';
I also suggest you take a look at autoloading. This will make file includes obsolete.
Files are included based on the file path given or, if none is given, the include_path specified. If the file isn't found in the include_path, include() will finally check in the calling script's own directory and the current working directory before failing.
You can use dirname(__FILE__) to get a path to the directory where the currently executed script resides:
include(dirname(dirname(__FILE__)) . '/tcpdf/config/lang/eng.php');
(since PHP 5.3, you can use __DIR__)
Or, define a constant in the first file that points to the root directory and use it in your includes.
I slightly remember from age old PHP days (years ago) that different functions wanted to have different paths. I mean...starting from different points. Some were relative, others absolute, etc.
How about fopen? Is that the same thing like require? Same path in same situation?
Paths are always relative to the initial script's location, even if the parser is going through an include that resides in a different directory.
To reliably work with paths relative to the current file, use
dirname(__FILE__)
or in PHP 5
__DIR__
in addition, as #troelskn points out below, require and include search the include_path.
include and require will look for a file relative to the setting given to it in php.ini first and foremost.
Say your ini file's include path entry is:
include_path = "var/www/includes;/var/www/PEAR"
Then in your scripts, no matter where in your document tree they are, eg
/var/www/html/website1/miles/down/in/folders/index.php
you just do this to include a file:
include 'settings.php' ;
As long as settings.php is one of the include_path folders, it will be included, then you can stop worrying about relative/absolute path relationships.
This setting can be altered in .htaccess files and per-file using ini_set() if you want too.
More on this:
http://php.net/manual/en/function.set-include-path.php
http://www.modwest.com/help/kb.phtml?cat=5&qid=98
or google for "include_path php"
Arg I'd like to comment but I can't...
#troelskn:
Include does NOT resolve to the include paths when you're using dirname(__ FILE __) because you are giving an absolute path to the include. The include paths are only searched when you DON'T give any path, only a filename (doesn't work with neither absolute nor relative paths).
If a path is defined — whether absolute (starting with a drive letter or \ on Windows, or / on Unix/Linux systems) or relative to the current directory (starting with . or ..) — the include_path will be ignored altogether.
http://php.net/manual/en/function.include.php
This question is very old, but there still happens to be some confusion around this. Different functions having different relative paths is still in place in some points. In example the following may not work as expected:
if(is_file($target)){
include $target;
}
is_file, is_dir, fopen - will use a path relative to the file which was requested by the HTTP request and will not be affected by set_include_path()
include, require - may have a different path assigned with set_include_path()
So more correctly the above code should look like:
if(is_file(get_include_path().'/'.$target)){
include $target;
}