tags:

views:

366

answers:

6

I have several PHP files include()ing other files from several other directories.

In one of those included files: foo/bar.php, I want bar.php to include 3 other files contained in the directory foo. However bar.php is actually included by another file in another directory, which is included by yet another file, and so on.

If I did:

include('./apple.php');
include('./orange.php');

In foo/bar.php, will it include the correct files from the foo directory regardless of which file included bar.php in itself?

+6  A: 

Use the following instead:

include(dirname(__FILE__).'/apple.php');

I don't know if what you've posted will work reliably or not, but this will.

Matthew Scharley
If you are using PHP 5.3.0 or later, you can use __DIR__. This is the same as dirname(__FILE__). http://us3.php.net/manual/en/language.constants.predefined.php
Bravery Onions
Oops, those boldfaced terms should have two underscores on each side. The link explains everything if I wasn't clear enough.
Bravery Onions
Using the latest and greatest features of PHP is a great way of introducing "but it works on my PC" bugs. Not every server has >=5.3.0, infact, I work on some servers that are still running PHP 4
Matthew Scharley
A: 

The last time I had that kind of problem I made an include directory out of my public_http root folder, and added its path to the include_path ini configuration. Had no more trouble including files. You can even add folders inside that custom include_folder for organization.

Say, you have header.php, footer.php, calendar.php and menu.php as "template" includes, and some functions/classes includes such as encription.php, authentication.php, permissions.php. You could store them all in your include folder such as:

  • custom-include-folder
    • template
      • header.php
      • footer.php
      • calendar.php
      • menu.php
    • libs
      • encription.php
      • authentication.php
      • permissions.php

And you include directly using

include 'template/header.php
Spidey
+2  A: 

No. Using ./ at the start of your include file name forces it to be searched from the "current directory" as set by your web server (most probably the directory of the initial script, or the DocumentRoot, depending on the webserver).

The way to get the behaviour you want depends on the value of your include_path (which can be modified with set_include_path() if necessary).

From the documentation for include():

Files for including are first looked for in each include_path entry relative to the current working directory, and then in the directory of current script. E.g. if your include_path is libraries, current working directory is /www/, you included include/a.php and there is include "b.php" in that file, b.php is first looked in /www/libraries/ and then in /www/include/. If filename begins with ./ or ../, it is looked for only in the current working directory or parent of the current working directory, respectively.

So, if there's no chance that the filename will be found in another directory in the include_path first, you could use include('apple.php').

If there is a possibility that apple.php exists elsewhere, and you want the copy in this folder to be used first, you could either use Matthew's suggestion, and

include(dirname(__FILE__).'/apple.php');

or, if you have many files to include from the current directory:

old_include_path = set_include_path(dirname(__FILE__));
include('apple.php');
include('orange.php');
include('peach.php');
include('pear.php');
set_include_path(old_include_path);
Stobor
You can use ini_get and ini_set in php < 4.3 if necessary.
Stobor
A: 

include() and require() will be relative to your current working directory getcwd(), which is usually the same directory of the requested script (at least under apache). However, if in CLI mode, it is what is inherited from $PWD;

Therefore,

include(dirname(__file__) . '/include.php');

is a good approach.

gahooa
A: 

Best practice is to include using absolute paths. You can define the common part of the path in a variable at your bootstrap file.
Why I think this is best practice:

  1. It negates such problems as you have.
  2. It is much more readable (and when you have an application with several hundred files, it will make it much more easier to find them).
  3. In terms of caching and the require/include_once functions this is the fastest way
Itay Moav
+1  A: 

As an aside, when including libraries you should usually use include_once() or require_once() to avoid problems with accidental circular or double inclusion.

deceze