PHP include file by relative path - php

This absolute path successfully includes my file httpapi.inc.php:
require_once '/home/devel/wwwroot/nm/dev/http-api/http-api/src/httpapi.inc.php';
The calling file is:
Caller relative:
/devel/phi/dev/appcenter-head/appcenter/application/nm/index.php
Caller location:
/home/devel/wwwroot/phi/dev/appcenter-head/appcenter/application/nm
Now, how can I include that same file based on a relative path like:
/devel/nm/dev/http-api/http-api/index.php
I must use this path "as is", since it is a config option passed by the user.

require() and include() should operate relative to the configured include paths and the currently executing script. So, this should work:
require_once('src/httpapi.inc.php');
To be perfectly precise, though, the current script's working directly is actually designated as one of the include paths in the default configuration. It won't work if you've mucked with it.
Using a . in the include path allows for relative includes as it means
the current directory.
Regarding your latest edit, your paths are different enough that it's simpler to just use the full path or add /home/devel/wwwroot/nm/dev/http-api/http-api/ to your config and use require_once('src/httpapi.inc.php').

You might use the document root from the $_SERVER variable:
http://www.php.net/manual/en/reserved.variables.server.php
require_once $_SERVER['DOCUMENT_ROOT'] . '/nm/dev/http-api/http-api/src/httpapi.inc.php';

include "src/httpapi.inc.php";

Related

Php 5.4 Include / require -- cannot get file path right

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.

include, require and relative paths

I'm not sure why I always have some many problems with this. Anyways this is the path to the file I want to require
/var/www/vhosts/mysite.com/htdocs/Classes/DBConnection.php
This is the path to the file that has the require statement
/var/www/vhosts/mysite.com/htdocs/Classes/Forecast/MyFile.php
and this is the require statement in MyFile.php
require_once '../DBConnection.php';
I keep getting the "failed to open stream" error. It works fine if I put in an absolute path. Does anyone see the problem here?
If /Classes/Forecast/MyFile.php is included from /index.php the relative path will be from the index file. To solve this, use __DIR__. The require will then be relative from that file.
require_once __DIR__.'/../DBConnection.php';
I have a detailed answer on this in another question:
finding a file in php that is 4 directories up
It explains the caveats of relative file paths in PHP. Use the magic constants and server variables mentioned there to overcome relative path issues.
Yep. The path is relative to the file your including your class file MyFe.php from and not the class file itself. I am assuming MyFile.php is not really the page being served, but an included or autoloaded class.
Make your path relative to the initially requested file. So if you're hitting /var/www/vhosts/mysite.com/htdocs/index.php, which includes MyFile.php, your path would be "Classes/DBConnection.php"

Is it a good idea to use $_SERVER['DOCUMENT_ROOT'] in includes?

Is this, for example, a good idea?
require_once($_SERVER['DOCUMENT_ROOT'].'/include.php');
If you have two virtual hosts on the same server, one for live and one for development, with different Apache DocumentRoots, this would avoid having to include absolute paths when the source of the include is unknown, and may be in any directory.
(Note: file paths in the following section are relative to the web root. They would in fact be like /var/www/app/core/init.php, where /var/www/app is the web root)
For instance: I have an /core/init.php which is called using relative paths from places all over the website (/file.php, /dir/file.php or /dir/dir/file.php).
This init.php then includes several function pages, in the fund directory, a subdir of /core (as in /core/func/userfunctions.php).
So, in init.php, I can use the $_SERVER method, because it breaks if I use a relative path and try to call functions from a page like /dir/file.php.
I can't see any problem with it, but in general what could go wrong?
I've seen cases where $_SERVER['DOCUMENT_ROOT'] is not set or is not what you would expect (i.e. not set in CLI or old IIS, or invalid in certain CGI setups).
For that reason you can use dirname(__FILE__) to obtain the path of the script that line is called in. You can then reference relative paths from there e.g.
include dirname(__FILE__) . '/../../other/file.php';
I go with the above method when the directory structure of the files is known and is not subject to change.
If DOCUMENT_ROOT is not available, the following is a suitable replacement:
substr($_SERVER['SCRIPT_FILENAME'], 0, -strlen($_SERVER['SCRIPT_NAME']));
You don't need to do this. PHP looks for the included file in the document root by default.
You can use set_include_path($new_include_path) to change this behaviour, or edit include_path in the php config file.
Also, from http://php.net/manual/en/reserved.variables.server.php:
'DOCUMENT_ROOT'
The document root directory under which the current script is executing, as defined in the server's configuration file.
For example, if you use URL rewriting, you will be very happy when you find out that the includes in your /there/are/so/many/paths/in/the/url/of/this/ page are still working!

Problem with require() when using a fully qualified URL

So, my code was using relative paths, but running into some problems with common files which could be include/required from different directory levels.
Absolute paths are more efficient anyway, right? So, I changed all include/require to absolute paths, using require_once('http://' . $_SERVER['HTTP_HOST'] . 'file_name.php');
$_SERVER['HTTP_HOST'] is correct, isn't it? It seemed so when I googled.
That required me to set 'allow_url_include=on` in php.ini and restart Apache.
So, now I have a situation that looks something like this (simplified example):
File2.php contains
<?php
function hello()
{
echo 'hello<br>';
}
?>
and if file1.php contains
<?php
require_once('file2.php');
hello();
?>
then I see the expected output "hello", but if I change that line to
require_once('http://' . $_SERVER['HTTP_HOST'] . '/file2.php');
Then I get "Fatal error: Call to undefined function hello() in C:\xampp\htdocs\file1.php"
(I guess that the reference to c:\xammp\httdos came from Xdebug, because PhpInfo shows HTTP_HOST localhost)
Anyway, that's a long post to say that I am missing some simple point and to ask what it is.
When you require a full URL, PHP makes a request to the server and gets back the output of the PHP script - this will not contain any actual PHP code (unless the script itself outputs PHP code).
Also, you aren't going to see any noticeable difference in performance between using relative and absolute paths, so don't worry too much about it. In fact, your path is not an absolute path but an absolute URI, and fetching a URI is actually going to be way slower than using local paths.
require_once expects a path on the server and not a URL. So for example you can't pass http://www.foo.com/test.php but you can do /var/www/foo/test.php. If you put http:// path then it will only include the output and not the php functions.
Absolute means relative to the file system. You're using url includes when you use http://..., but you're using normal includes when you use file2.php. To use real absolute paths use require_once('/xampp/htdocs/file2.php');.
When you require or include a file in PHP, the file is merged into the current script from the local filesystem unless the file path includes a schema such as HTTP, then it will be included by one of the fopen wrappers. See http://www.php.net/manual/en/function.include.php
PHP determines the full path to the file based on certain factors.
An absolute path (one beginning with a DIRECTORY_SEPARATOR (eg /) or drive letter identified (eg C:\) for Windows servers) is the quickest as there is no translation to do. The file is simply merged in from the given location.
A relative path however is much more complex than most imagine.
PHP will search for the relative path in the include_path stack (FIFO). This is a PATH_SEPARATOR (;) delimited string containing one or more "base" paths.
An example include path is
/usr/share/pear;.
This contains two paths, /usr/share/pear and ., the current working directory (CWD).
You will receive the best performance in your application if you specifically set your include path and remove anything not relevant. For example, say all your "includable" files reside in /home/me/www/appname/includes, your best bet is to set this in your bootstrap / common script, eg
set_include_path('/home/me/www/appname/includes');
Now any relative include call will only fetch from this location.
If you need to set multiple paths, I find something like this works well
set_include_path(implode(PATH_SEPARATOR, array(
'/include/path/one',
'/include/path/two'
)));
and if you want to ammend the server include path, I'd advise to add it in the same way but place it at the bottom of the stack, eg
set_include_path(implode(PATH_SEPARATOR, array(
'/include/path/one',
'/include/path/two',
get_include_path()
)));
IMHO, one of the best things you can do is remove the CWD from the include path as it tends to be one of the biggest sources of "include path hell". If you do need to include a file relative to the current one, use
require_once realpath(dirname(__FILE__)) . '/relative/path/to/file.php';
You can use file_get_contents function
file_get_contents('http://' . $_SERVER['HTTP_HOST'] . '/file2.php');
But it is mainly useful for connecting to an external domain

Path Confusion: Does require, include, fopen etc. take all their paths the same way?

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;
}

Categories