views:

317

answers:

1

Am having problems with PHP's require_once, require, include_once and include functions not correctly resolving a file. I am running PHP 5.3.1 on Windows Vista with Apache 2.2.11.

These are the problems I am getting:

file_exists('C:/wamp/www/park_factor_network/system/application/shared/config/language.php')

returns TRUE

is_readable('system/application/shared/config/language.php')

returns TRUE

$fp = fopen('C:/wamp/www/park_factor_network/system/application/shared/config/language.php','r');
$contents = fread($fp, filesize('C:/wamp/www/park_factor_network/system/application/shared/config/language.php'));

returns a valid file resource and stores it into $contents

However:

require_once('system/application/shared/config/database.php') or die("Cannot Include Language Config");
require_once('C:/wamp/www/park_factor_network/system/application/shared/config/language.php') or die("Cannot Include Language Config");

return:

Fatal error: require_once() [function.require]: Failed opening required '1' (include_path='.;C:\php5\pear') in C:\wamp\www\park_factor_network\system\application\shared\hooks\select_language.php on line 25

C:\wamp\www\park_factor_network\system\application\news_site\hooks is a Directory Junction for C:\wamp\www\park_factor_network\system\application\shared\hooks

I only experience this problem when accessing this file from a certain location in the framework, however as this is a direct include or require it shouldn't be affected by that and only PHP? If I try and include the file anywhere else within my setup it loads fine.

+3  A: 

require_once is a language construct. It is not a function and has no return value.

Brackets around the file name parameter are optional. This seems to mean that in this line:

require_once('system/application/shared/config/database.php') 
             or die("Cannot Include Language Config");

the whole expression

('system/application/shared/config/database.php') 
 or die("Cannot Include Language Config");

is evaluated (returning 1) and used as the file name argument. 1, obviously, doesn't exist.

What you are doing doesn't make real sense though, because include will not return false when loading a file fails. require_once() will terminate the script's execution anyway. If you take care of switching of error reporting in your production environment, you could easily live with a PHP Fatal Error telling you the file doesn't exist (instead of your custom die()).

If you need to gracefully exit the script, I would do a file_exists call before the statement, and die() when that fails:

$file = 'system/application/shared/config/database.php';

if ((!is_file($file)) or(!is_readable($file)))
   die("Cannot Include Language Config");

require_once('system/application/shared/config/database.php');
Pekka
+1 for a great spot and detailed explanation.
Jason McCreary
Thanks very much for clear answer. It now makes perfect sense several of us over at php freaks IRC were trying to get our head round the file resolving and it was nothing to do with that at all.
Ian Cant
Instead of `file_exists` you should better use `is_file` and `is_readable` since `file_exists` does also return true for directories and a (regular) file should also be readable.
Gumbo
Good point @Gumbo, edited.
Pekka
Sorry should have made this a little clearer in my explanation I was only using file_exists and is_readable to prove the file was there.
Ian Cant
@Ian but it's the right way to check beforehand, better than `file_exists()`. (But if you're fine with a Fatal Error, you don't really need it.)
Pekka