Linux: File both exists and not exists - php

I am writing a PHP application, and I've just encountered a really wierd error. After a recent move to a new (Ubuntu) server, i started getting fatal errors on a require_once statement. So obviously the file doesn't exist, or the file permissions are wrong, right?
No, as it turns out:
The file does exist
The file is checked out from an SVN repository. When I go into the folder and list the files (ls or ls -l) the file is clearly there and has the correct file size. When I update the file in the repository and update the working copy, the changes are copied to the working copy. The file has permissions 755, so everyone should be able so see and read it. Other files in the same directory are working just fine.
The file also doesn't exist:
PHP exits with a fatal error because the file can't be found. If I use the find-command, the file is not found. If I try to use nano to edit the file, it claims it does not exist. If I start typing the filename and press tab to autocomplete, it can't find the file.
This behaviour has now happened on two separate servers, but it works fine on a third server. All the servers run Ubuntu 10.04.
Does anyone have any idea what is going on?
EDIT:
File name is AdminIpv4RangeAddFormHandler.inc.
Full error message, with file paths obscured:
Warning: require_once(fullpath/AdminIpv4RangeAddFormHandler.inc): failed to open
stream: No such file or directory in fullpath/anotherfile.inc on line 34 Fatal error:
require_once(): Failed opening required 'fullpath/AdminIpv4RangeAddFormHandler.inc'
(include_path='.:/usr/share/php:/usr/share/pear') in fullpath/anotherfile.inc on line
34
The following command produces no output:
find -name AdminIpv4RangeAddFormHandler.inc -ls
A regular ls -li outputs (amongst others) this row:
2233407 -rwxr-xr-x 1 root root 1597 2011-12-13 08:02 AdminIPv4RangeAddFormHandler.inc

Be careful switching OS's, as some are case sensitive, and others aren't.
I use my Mac for development (case insensitive), so it doesn't matter what casing I use for file_exists() or include_once() etc. Then I deployed to Ubuntu 11 (case sensitive), and all my includes stopped working. I suspect you have the same exact problem.
The tricky part for me was, while using git, my version control didn't detect changes in file name case as a modification. I actually had to rename every file with some sort of prefix, commit and deploy, rename them back to what they should be (with consistent capitalization!), and finally commit and deploy again. It was a complete pain.
Moral of the story--code for your production system, not your dev system.

Take a good long look at your filenames:
AdminIpv4RangeAddFormHandler # from PHP
AdminIpv4RangeAddFormHandler # from find command
AdminIPv4RangeAddFormHandler # from ls output
^
You should pick IP or Ip and stick with the decision everywhere.

Related

Why isn't PHP.ini include_path working correctly for me here?

I'm experiencing some weirdness trying to setup PEAR on my development machine (Windows XP).
The process is simple enough and everything makes sense, but I'm trying to use one of the installed packages which calls on the PEAR.php file and am getting:
Failed opening required 'PEAR.php' (include_path='.;C:\Program Files\PHP\PEAR')
It's a pretty straightforward error to get assuming the file/path doesn't exist, except I've checked and double checked - it absolutely does - right down to capitalisation (which I know doesn't matter on Windows normally but still...)
What can I possibly have overlooked that means the file can't be opening?
Just to re-iterate, the file/dir DEFINITELY exists as C:\Program Files\PHP\PEAR\PEAR.php - and I have also tried:
forward slashes
short dir names (Progra~1)
all lower case (even though the files are as is) and even setting the include path to
ONLY that directory.
test.php in same directory
test.php in c:\ and with include path set to c:\ and just \
PHP (5.2.6) is NOT running in safe mode, and the web server is Apache 2.
Maybe your php configuration has open_basedir set? If so, set it's value to none.
Try one of these:
C:/Program\ Files/PHP/PEAR/PEAR.php
C:/Program Files/PHP/PEAR/PEAR.php

move_uploaded_file() gives a Owner/Group error

I'm using move_uploaded_file() to upload images to the server, however it gives the usual error of:
Warning: move_uploaded_file(upload/file.png) [function.move-uploaded-file]:
failed to open stream: No such file or directory in
/home/newuser/public_html/model/account.class.php on line 39
Warning: move_uploaded_file() [function.move-uploaded-file]: Unable to move
'/tmp/phpuLkUgE' to 'upload/file.png' in
/home/newuser/public_html/model/account.class.php on line 39
This is not permission based as I have set the folder to 777 with root access and ls -l displays it correctly as this.
755 /home/newuser/public_html/model
755 /home/newuser/public_html/model/account.class.php
777 /home/newuser/public_html/upload
PHP Line
move_uploaded_file($_FILES["photo"]["tmp_name"], "../upload/file.png");
The problem I think is down to the Owner/Group setting being configured incorrectly .. a while back I had all of my sites as subdomains in one account:
/home/olduser/public_html/subdomains/index.html
I then changed this and created a new user account to manage a separate website easier and just moved the files across ...
/home/olduser/public_html/subdomains
/home/newuser/public_html/index.html
The new folders in /home/newuser are now owned and grouped as newuser newuser but I think php may be running as nobody olduser so this could be causing the issue?
What can I try to fix this?
Permissions to a particular file / directory don't just apply on the directory itself, but on the whole path leading up to it.
Example:
/home/ - needs 'x' permission (execute)
/home/newuser/ - needs 'x' permission
/home/newuser/public_html/ - needs 'x' permission
/home/newuser/public_html/avatar/ - needs 'wx' permission (execute + write)
It was kind of touched on indirectly in Silver89's feedback under Jack's Answer, but not outright stated - so I wanted to provide an answer to what helped me with this issue which had me scratching my head for a long time. ;)
The best approach that I have found for the destination of move_uploaded_file() is to use the full absolute path. It can vary based on whether you are on a Unix\Linux server or Windows server, but this should give you the basic idea.
On my Unix server at work, you cannot use "../anything" but have to use the full absolute internal file path of /var/www/html/uploads/imagename.jpg.
So that is why your last test worked for you, Silver89 - because your server was probably trying to upload the image to http://yourservername.com/upload/file.png instead of http://www.yourservername.com/yoursubfolder/upload/file.png. It probably threw out the "../" part altogether and that folder didn't exist on the server.
You can find out what that full path name is by logging onto the server (terminal/ssh etc.) and issuing the 'pwd' command or by using PHP code and echoing the getcwd() command in a stripped php file in the folder where your images will go.
This site is helpful in figuring this out based on your server using different PHP Server Config Checking Functions - See the table midway down. You can simply echo these out to the screen such as:
echo $_SERVER["SCRIPT_FILENAME"].
This was a tough one for me so I hope this makes it a little easier for the next person to find - even if this is 8 months old. ;)

PHP Fatal Error Failed opening required File

I am getting the following error from Apache
[Sat Mar 19 23:10:50 2011] [warn] mod_fcgid: stderr: PHP Fatal error: require_once() [function.require]: Failed opening required '/common/configs/config_templates.inc.php' (include_path='.:/usr/share/pear:/usr/share/php') in /home/viapics1/public_html/common/configs/config.inc.php on line 158
I am definately not an expert of Apache but the file config.inc.php & config_templates.inc.php are there. I also tried navigating to a test.html page I placed in common/configs/ so I assume there is no rights issues going on. I also set the rights on config_templates.inc.php to give everyone read, write, and execute rights. Not sure what to do at this point, I checked to see if there was a /usr/share/php directory and I found there was not but when I did yum install php it said it had the latest. Ideas?
It's not actually an Apache related question. Nor even a PHP related one.
To understand this error you have to distinguish a path on the virtual server from a path in the filesystem.
require operator works with files. But a path like this
/common/configs/config_templates.inc.php
only exists on the virtual HTTP server, while there is no such path in the filesystem. The correct filesystem path would be
/home/viapics1/public_html/common/configs/config_templates.inc.php
where
/home/viapics1/public_html
part is called the Document root and it connects the virtual world with the real one. Luckily, web-servers usually have the document root in a configuration variable that they share with PHP. So if you change your code to something like this
require_once $_SERVER['DOCUMENT_ROOT'].'/common/configs/config_templates.inc.php';
it will work from any file placed in any directory!
Update: eventually I wrote an article that explains the difference between relative and absolute paths, in the file system and on the web server, which explains the matter in detail, and contains some practical solutions. Like, such a handy variable doesn't exist when you run your script from a command line. In this case a technique called "a single entry point" is to the rescue. You may refer to the article above for the details as well.
If you have SELinux running, you might have to grant httpd permission to read from /home dir using:
sudo setsebool httpd_read_user_content=1
Run php -f /common/configs/config_templates.inc.php to verify the validity of the PHP syntax in the file.
You could fix it with the PHP constant __DIR__
require_once __DIR__ . '/common/configs/config_templates.inc.php';
It is the directory of the file. If used inside an include, the directory of
the included file is returned. This is equivalent to
dirname __FILE__ . This directory name does not have a trailing slash
unless it is the root directory. 1
Just in case this helps anybody else out there, I stumbled on an obscure case for this error triggering last night. Specifically, I was using the require_once method and specifying only a filename and no path, since the file being required was present in the same directory.
I started to get the 'Failed opening required file' error at one point. After tearing my hair out for a while, I finally noticed a PHP Warning message immediately above the fatal error output, indicating 'failed to open stream: Permission denied', but more importantly, informing me of the path to the file it was trying to open. I then twigged to the fact I had created a copy of the file (with ownership not accessible to Apache) elsewhere that happened to also be in the PHP 'include' search path, and ahead of the folder where I wanted it to be picked up. D'oh!
you can set the include path in php.ini
include_path = ".:/home/viapics1/public_html"
I was having the exact same issue, I triple checked the include paths, I also checked that pear was installed and everything looked OK and I was still getting the errors, after a few hours of going crazy looking at this I realized that in my script had this:
include_once "../Mail.php";
instead of:
include_once ("../Mail.php");
Yup, the stupid parenthesis was missing, but there was no generated error on this line of my script which was odd to me

open a file in PHP CLI

The file was created by apache using mkdir() and fopen() etc..
How do i let my php CLI program be allowed to read that file that apache (that is what it says the user is) created so i dont get this error:
Warning: file_get_contents(./sessions/nl2larsjl6n3315mesghmspts7.txt): failed to open stream: No such file or directory in /var/www/html/cli.php on line 58
in the cli this my code for getting the file:
$alert = file_get_contents('./sessions/'.$sessionID.'.txt');
Short answer:
when you create it, you should run chmod(0777) on it.
Long answer:
chmod(0777) means "world readable and writable, and not actually recommended. Checkout http://en.wikipedia.org/wiki/Filesystem_permissions, http://www.linuxforums.org/articles/file-permissions_94.html for a complete explanation on these numbers.
Basically if you need it to be writable by a user, and readable by any user, do a chmod(0644)
EDit: i was quick to wrinte an answer... without reading the question carefully.
You seem to try and open the file from a different directory than the folder where you created it.
Try and see the result on echo getpwd() in the CLI script and then in the script running under www. I bet you will see different locations.
When executing CLI scripts you should either do a chdir() before running the command or use absolute paths at all times for the files you access.
I personally prefer the chdir() method.

Same-directory includes failing on a Fedora server with PHP

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.
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.
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 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.
Mounting the CIFS share with the option 'noserverino' should resolve the issue, for example:
mount -t cifs -o noserverino //host/share /mnt
Full explanation of why this works can be found here: http://www.php.net//manual/en/function.is-dir.php#98338

Categories