tags:

views:

1099

answers:

9

As many do I have a config.php file in the root of a web app that I want to include in almost every other php file. So most of them have a line like:

require_once("config.php");

or sometimes

require_once("../config.php");

or even

require_once("../../config.php");

But I never get it right the first time. I can't figure out what php is going to consider to be the current working directory when reading one of these files. It is apparently not the directory where the file containing the require_once() call is made because I can have two files in the same directory that have different paths for the config.php.

How I have a situation where one path is correct for refreshing the page but an ajax can that updates part of the page requires a different path to the config.php in the require_once() statement;

What's the secret? From where is that path evaluated?

Shoot, I was afraid this wouldn't be a common problem - This is occurring under apache 2.2.8 and PHP 5.2.6 running on windows.

A: 

The only place I've seen the path evaluated from is the file that you are currently editing. I've never had any problems with it, but if you are, you might want to provide more information (PHP version, OS, etc).

Thomas Owens
+4  A: 

I like to do this:

require_once(dirname(__FILE__)."/../_include/header.inc");

That way your paths can always be relative to the current file location.

bobwienholt
That's kind of cool. So require_once doesn't typically use the current file location on its own?
dl__
I believe that everything is relative to the main PHP file's path. So if you have nested includes or requires in different directories, things get hairy.
bobwienholt
I use a bunch of classes from all over the dir tree and I use them from different php files. That might be why I'm having these issues.
dl__
+2  A: 
Kent Fredric
Yeah, the config.php is in the root of the web app so I'd like to say require_once("/config.php"); but that doesn't seem to work either. I'd expect that to work everytime.
dl__
+1  A: 

Since require and require_once are very similar to include and include_once, all the documentation is posted under the "include" functions doc area on php.net From that page

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 only in the current working directory.

Further, you can find all the current include paths by doing a "php -i" from the command line. You can edit the include path in your php.ini file, and also via ini_set(). You can also run the php_info() fucntion in your page to get a printout of your env vars if the CLI is inconvenient.

Zak
A: 

Take a look at the function getcwd. http://us2.php.net/getcwd

andyh_ky
+1  A: 

If you have sufficient access rights, try to modify PHP's include_path setting for the whole site. If you cannot do that, you'll either have to route every request through the same PHP script (eg. using Apache mod_rewrite) or you'll have to use an "initialization" script that sets up the include_path:

$includeDir = realpath(dirname(__FILE__) . '/include'); 
ini_set('include_path', $includeDir . PATH_SEPARATOR . ini_get('include_path'));

After that file is included, use paths relative to the include directory:

require_once '../init.php'; // The init-script
require_once 'MyFile.php'; // Includes /include/MyFile.php
Ferdinand Beyer
I believe I do have access to the include directory
dl__
+7  A: 

The current working directory for PHP is the directory in which the called script file is located. If your files looked like this:

/A
   foo.php
   tar.php
   B/
       bar.php

If you call foo.php (ex: http://example.com/foo.php), the working directory will be /A/. If you call bar.php (ex: http://example.com/B/bar.php), the working directory will be /A/B/.

There is where it gets tricky. Let us say that foo.php is such:

<?php
require_once( 'B/bar.php' );
?>

And bar.php is:

<?php
require_once( 'tar.php');
?>

If we call foo.php, then bar.php will successfully call tar.php because tar.php and foo.php are in the same directory which happens to be the working directory. If you instead call bar.php, it will fail.

Generally you will see either in all files:

require_once( realpath( dirname( __FILE__ ) ).'/../../path/to/file.php' );

or with the config file:

// config file
define( "APP_ROOT", realpath( dirname( __FILE__ ) ).'/' );

with the rest of the files using:

require_once( APP_ROOT.'../../path/to/file.php' );
Seamus
A: 

The path of the PHP file requested in the original GET or POST is essentially the 'working directory' of that script. Any "included" or "required" scripts will inherit that as their working directory as well.

I will either use absolute paths in require statements or modify PHP's include_path to include any path in my app I may want to use to save me the extra typing. You'll find that in php.ini.

include_path = ".:/list/of/paths/:/another/path/:/and/another/one"

I don't know if it'll help you out in this particular instance but the magical constants like FILE and DIR can come in handy if you ever need to know the path a particular file is running in.

http://us2.php.net/manual/en/language.constants.predefined.php

Michael Luton
Seems to me the problem with that would be that I have test sites and a live site so that the absolute paths would be different. Maybe I should just load up the include path.
dl__
+1  A: 

I include this code at the top of every page:

//get basic page variables
$self=$_SERVER['PHP_SELF']; 
$thispath=dirname($_SERVER['PHP_SELF']);
$sitebasepath=$_SERVER['DOCUMENT_ROOT'];

//include the global settings, variables and includes

include_once("$sitebasepath/globals/global.include.php");

Include and require both take either a relative path or the full rooted path. I prefer working with the full path and make all my references like the inlcude statement above. This allows me to enter a general variable $sitebasepath that handles account specific information that may change from machine to machine and then simply type the path from the webroot, ie. /globals/whatever_file.php

I also use the $self variable in forms that may call themselves to handle data input.

Hope that helps.

Steve Massing