views:

39

answers:

2

I have a couple files that look like this:

index.php:

<?php  
include('includes/header.php');

...

includes/header.php:

<?php
include('config.php');

...

The error I get is

Warning: require(config.php) [function.require]: failed to open stream: No such file or directory in [dir]/includes/header.php on line 2
Fatal error: require() [function.require]: Failed opening required 'config.php' (include_path='.:/usr/share/pear:/usr/share/php') in [dir]/includes/header.php on line 2

I did some further debugging: when I add the call

system('pwd');

to includes/header.php, it shows [dir], where it should say [dir]/includes. Adding the 'includes/' to the include path works, but isn't desirable because that would fail on the production server.

The above code works on a production server, and worked fine on my development Fedora server, until I tried to change my development environment so that the Fedora server's document root is a mounted CIFS share.

Any ideas? Thanks.

A: 

worked fine ... until I tried to change my development environment so that the Fedora server's document root is a mounted CIFS share.

Is SELinux enabled?

Check /var/log/audit/audit.log

I'm going to wager that SELinux is enabled and in enforcing mode, and is interfering.

Charles
Yes, they're both in the same directory. And ../config.php didn't work, like I said, it's as if it's in the parent directory, because include 'includes/config.php' does work.
JimmySawczuk
I rewrote my answer because I realized I was wrong moments after I posted. Please check my update for something that might actually be correct this time. ;)
Charles
It's currently in permissive mode, SELinux was one of the first things I checked (it's pretty much the bane of my existence) and I weeded out a couple problems that way. audit.log isn't showing anything that seems like a denial.
JimmySawczuk
What's the output of `realpath(\_\_FILE__)` from inside the header? What's the output of `dirname(\_\_FILE__)`? The directory given in dirname should be the same exact path as given in realpath, and both should match the location of the file. Does including config.php work when given a fully qualified path based on the modified results of `dirname(\_\_FILE__)`?
Charles
`realpath(__FILE__)` is empty, the `dirname(__FILE__)` is correct and `require(dirname(__FILE__).'/config.php'))` works. It seems that maybe that realpath value isn't getting populated correctly?
JimmySawczuk
`realpath` attempts to resolve the path, then asks the filesystem if the path is valid. If it returns nothing, then the filesystem says the path does not exist. The `\_\_FILE__` token represents the path to the file being executed (in this case, includes/header.php). The fact that `realpath` returned nothing for the current file should speak volumes to the level of WTF you're experiencing... I have no further suggestions that would be productive.
Charles
I did a little research, turns out `realpath` returns `false` when it doesn't have execute permissions on one of the directories in the path. So I think my problem now lies in trying to make a Windows 7 share talk to a Samba client with the right permissions.
JimmySawczuk
A: 

I hate to say it, but the behavior with pwd that you're describing is 100% expected behavior (and has been since at least PHP4... probably earlier).

PHP automatically sets the current working directory (used by pwd) ONCE. PHP does not change it. Thus, . will refer to the original current working directory unless you manually change it with chdir().

There are various solutions to this problem used; most of which you can see at http://stackoverflow.com/questions/339202/php-include-file-strategy-needed.

If it worked before, there was probably some updating of the include_path somewhere, code that changed the the working directory no longer changes it, or the php version you used that implemented this odd (but more expected) behavior no longer does so.

Anyways, I'd check the include paths: ini files, or scripts that change the include path. I'm guessing something used to update the include_path, but no longer does so.

I'm not sure about the details of how you moved it but I've encountered some annoying scripts where an .htaccess set an auto_prepend_file to a hardcoded path to a file completely outside the website structure, that set the include path (among other things) to somewhere inside the web structure.

AlReece45