php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #40666 handling of relative paths in include()
Submitted: 2007-02-28 12:39 UTC Modified: 2015-01-08 21:21 UTC
Votes:11
Avg. Score:4.6 ± 0.6
Reproduced:11 of 11 (100.0%)
Same Version:5 (45.5%)
Same OS:6 (54.5%)
From: mfr at bmx-chemnitz dot de Assigned:
Status: Not a bug Package: *General Issues
PHP Version: 5.2.1 OS: all
Private report: No CVE-ID: None
 [2007-02-28 12:39 UTC] mfr at bmx-chemnitz dot de
Description:
------------
To start with, PHP version is irrevelant for this request, regardless what your bug report form says.

This is Change Request.

Change the way relative includes are handled.

The current way of NOT using the script directory but the current working directory, while documented, cannot be considered a feature but is clearly a bug.
A script should NOT have to worry about where it was included from when it needs to include other files, regardless of the way it includes them (relative, absolute, relative with "./" / "../").

The way this is implemented generates confusion and, quite frankly, breaks stuff. Pushing responsibility to properly deal with basic functionality like this to the user is just wrong.


Following this up with an intended reply to bug #22865:

I am sorry, but how can this not be a bug?

You say the documentation says that
"Relative paths in include/require are always relative to the initial
script, *not* to the file doing the include-ing."

Which, regarding the state of documention, is all fine and well, given that the documentation describes the wrongness of the behaviour correctly.

HOWEVER, the behaviour itself is the bug.
How can it be intended that, in any given file, any relative include has to know where the originally called file is located? Why should it care? How would it know?
If I have a file x that just knows it needs file y in the parent directory, then this is all there should be to it.

You claim that "You will need to use some kind of tracking of the base path for the current invocation.". Pardon me, but this is exactly the kind of house-keeping that include() itself is supposed to do.

Reproduce code:
---------------
foo/bar.php:
<?php
 echo "foo/bar.php ";
 include("../baz.inc");
?>

baz.inc:
<?php
 echo "baz.inc ";
?>

index.php:
<?php
 echo "index.php ";
 include("foo/bar.php");
?>

Expected result:
----------------
http://host/foo/bar.php
"foo/bar.php baz.inc"

http://host/index.php
"index.php foo/bar.php baz.inc"

Actual result:
--------------
http://host/foo/bar.php
"foo/bar.php baz.inc"

http://host/index.php
"index.php foo/bar.php
 Warning: main(../test.inc) [missing file...]"

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-01-08 21:21 UTC] ajf@php.net
-Status: Open +Status: Not a bug -Package: Feature/Change Request +Package: *General Issues
 [2015-01-08 21:21 UTC] ajf@php.net
It's not the most ideal behaviour, I'll give you that. It is, however, the behaviour we've had for a long time.

I suggest just doing this:

    require_once __DIR__ . '/../baz.inc';

That should do what you want.

Also, I'm not sure this is necessarily incorrect behaviour. Both including based on the original script's path and including based on the current file's path have their own advantages. On balance, the former is possibly better, since you can get the latter's behaviour by merely prefixing __DIR__, but the former's behaviour cannot be gotten easily with the latter, and there are legitimate reasons you might want to follow it.
 
PHP Copyright © 2001-2026 The PHP Group
All rights reserved.
Last updated: Tue Oct 06 22:00:02 2026 UTC