PHP / Relative requires

From WhyNotWiki
Jump to: navigation, search

Problem

web/page_A.php has:

<?php
require_once "top.php";
?>

web/top.php has:

<?php
require_once '../php/init.php';
?>

That works well enough ... until you try to include the same file (web/top.php) from a PHP script that is in a subdirectory of web...

Suppose you have web/products/page_B.php with:

<?php
require_once "../top.php";
?>

You'd think everything would still work, right? At least I would. Because to me it is most intuitive for each script to refer to other files relative to themselves. But that's not the way PHP works, unfortunately. It appears that PHP handles the paths relative to the script that was requested by the web server (command-line, etc.?).

So because web/products/page_B.php was requested, this line in web/top.php:

require_once '../php/init.php';

actually inadvertently requests the file web/php/init.php, which of course cannot be found. It would have to specify '../../php/init.php' to correctly request php/init.php in the case of web/products/page_B.php -- but then it wouldn't work for the case of web/page_A.php!

Clearly, it would be desirable to be able to require paths relative to the file we're in! Fortunately, this is possible. Unfortunately, it's rather verbose and a pain to type.

Solutions

require_once dirname(__FILE__) . '/../php/init.php';


Other solutions/suggestions

http://us3.php.net/require_once. Retrieved on 2007-05-11 11:18.

<?php
function & rel($r, &$f) {return file_exists( ( $f = ( dirname($r).'/'.$f ) ) );}
function & relf($r, $f) {return rel($r,$f) ? file_get_contents($f) : null;}
function & reli($r, $f) {return rel($r,$f) ? include($f) : null;}
function & relr($r, $f) {return rel($r,$f) ? require($f) : null;}
function & relio($r, $f) {return rel($r,$f) ? include_once($f) : null;}
function & relro($r, $f) {return rel($r,$f) ? require_once($f) : null;}
?>

I found it useful to have a function that can load a file relative to the calling script and return null if the file did not exist, without raising errors.

...

<?php
/*
Require the file once.
It's like suppressing error messages with @ but only when the file does not exist.
Still shows compile errors/warning, unless you use @relro().
Relative to the file calling the function.
*/
relro(__FILE__, 'stats.php');
?>


If you work with a deep php file structure and a barrage of includes/requires/file-loads this works well.

Ads
Personal tools