How do I get something more meaningful than 'FALSE' when I can't open a file.
$myFile = "/home/user/testFile.txt";
$fh = fopen($myFile, 'w') or die("can't open file");
When I use the die statement, can't open file is returned to the client, and it is almost useless. If I remove it, no error is raised. If I return $fh it is FALSE. I tried both local file name and absolute file name. My index.html file is in one of the sub folders of my hole folder. Furthermore, I am using suPHP with the folder I am trying to write to having a permission of 0755 (suPHP requires this for all folders).
How do I figure out why there was a problem, or at least query it before trying to open the file.
Use error_get_last() to catch the (supressed) errors in php:
$f = #fopen("x", "r") or die(print_r(error_get_last(),true));
fopen should raise an E_WARNING if it fails. See error_get_last or set_error_handler(*) to catch it. Other than that you can use file_exists and is_readable to check whether the file is missing or there's another (probably permission-related) problem.
(*) I consider it good practice to always set an error handler that turns all PHP errors into exceptions.
Related
I have this stupid little test PHP script running on a Ubuntu system inside an instance of a virtual server (Oracle Virtual Box) running on my pc:
<?
error_reporting(E_ALL);
ini_set('display_errors', 1); // show errors
echo "<p>test</p>";
$filename = "andy.txt";
$fh = fopen($filename, 'w') or die('fopen failed');
fwrite($fh, "qwerty") or die('fwrite failed');
fclose($fh);
?>
Despite all appropriate directory and file permissions being set, it is failing on the fwrite. The fopen works and creates the file, so write access is clearly enabled, but the fwrite dies, and the 'fwrite failed' message is output (no other error output is displayed).
The same script works perfectly well when I upload to my real server, so I am completely stumped as to why it won't write to the file; maybe it's something about my virtual server that is causing the problem.
Seems like such a pathetic thing, but it's driving me nuts! Considerable time Googling has failed to yield an answer, so can anybody here please provide some insight? Many thanks.
Not sure why the fwrite() call would die, as it returns the number of bytes written.
That said, have you tried with file_put_contents() instead? It's a simpler way of writing to a file, and is the recommended way since early PHP 5.
With it you only need to do the following
$filename = "andy.txt";
if(!file_put_contents ($contents, $filename)) {
// Write failed!
}
No need to bother with opening and closing the file pointer, as that's automatically handled by the function. :)
Solved! It was a disk space error on my virtual server. At the back of my mind, I knew I had seen this mentioned elsewhere as an issue with write fails, but in this case I failed to make the connection.
#ChristianF Thanks! Switching to file_put_contents() was very helpful, since it also failed, but gave me a meaningful error message:
'file_put_contents(): Only 0 of 6 bytes written, possibly out of free disk space'
Aha! Having recalled that growing log files can be a problem, I took it upon myself to delete everything inside /var/log (after saving them) and Presto! it now works! So, thank you for that tip - I will switch to using file_put_contents from now on. BTW: The contents of error.log itself was 2GB, while the remaining size of everything else in /var/log was only about 15MB, but deleting error.log by itself did not work, so I deleted everything.
#Clayton Smith Thank you, but removing the "or die('fwrite failed')" part did not result in any further error info - which is what is so frustrating: It's a shame that those error reporting directives at the start of the script didn't seem to do much.
#NaeiKinDus Thank you, but I don't think I have SELinux running (I'm afraid I don't know anything about this). Although I have a /etc/selinux directory present, there's no config file in it, just what appears to be a skeleton semanage.conf - whatever that is. Commands such as sestatus are not recognised.
This is a PHP script running under Windows. It had been working but has recently stopped.
The file is opened and a valid file handle is returned: $fh = fopen($filename, 'r');
However, the very first time I call fgetcsv it returns false:
$headers = fgetcsv($fh, 6000, ',');
$line_no++;
if($headers === FALSE){
echo 'Error parsing file headers';
}
This is now happening on all csv files I try. Other changes I have tried to no avail are:
ini_set('auto_detect_line_endings', true); Right before opening the file
rewind($fh); Right after opening the file
Using both 0 or a number like 6000 for the second parameter, length.
Changing the file's line endings style from unix to Windows and Mac
It seems like something with Windows is causing this file not to parse.
Is there any way to return the actual error from fgetcsv? The documentation doesn't say there is, just that it returns false on any error. Are there other Windows settings that could be causing issues? The Windows security settings give everyone full control of the files.
The issue turned out to be that a change at the beginning of the script was using the same file as a lock file so the script wouldn't be run on the same file twice at the same time. Then, later in the script when I actually wanted to parse the file, I opened it again (which was successful), but then I couldn't actually read the contents.
The solution I used was to create a temporary lock file based on the filename instead of using the actual file. Eg: $filename.'.lock'
It was a silly mistake on my part, however it would have been much more helpful if PHP had returned or written an error/warning at some point.
The canonical way to debug this would be "print_r($headers)".
As fgetcsv returns an array, it must be empty or a non-array. If you can configure (or have configured) PHP to log errors to a known location (Windows with IIS would be "syslog" and should show up in the Event Viewer), you should be able to figure out what's wrong.
The PHP file_put_contents function works perfectly fine when the file exists. If the file does not exist I receive the error "failed to open stream: No such file or directory".
$file = '../templates/stuff.xml';
if (!file_exists($file)) {$file = '../'.$file;}
$var['xhtml'] = $_POST['post_xhtml'];
$file_contents = serialize($var);
file_put_contents($file,$file_contents);
I tried the same thing with fopen and fwrite using the correct flags (w, w+ and tried the others) yet still had the same problem: if the file already existed it worked just fine, otherwise it would give me the same error message.
I know the file path is correct. I'm using Windows 7 for local development.
When the file doesn't exist, you are prepending ../ to the path, thus you are trying to write to:
../../templates/stuff.xml
Are you sure that the folder ../../templates exists (and that PHP can write to it)?
Before you write to a file, you need to check that the folder exists. Try using is_dir():
if(is_dir(dirname($file))){
file_put_contents($file, $file_contents);
}
I'm want to read a simple string from a text file which is around 3-4 mb but fopen() fails ("can't open file" from die() is called). Here's the code:
clearstatcache();
$fh = fopen("/my/path/to/file.txt", "r") or die("can't open file");
$sql = fread($fh,filesize("/my/path/to/file.txt"));
Have you firstly checked to see if the file exists?
if (!file_exists("/my/path/to/file.txt") {
die('File does not exist');
}
clearstatcache();
$fh = fopen("/my/path/to/file.txt", "r") or die("can't open file");
$sql = fread($fh,filesize("/my/path/to/file.txt"));
you have to add to your code this line
error_reporting(E_ALL);
and ALWAYS keep this line in ALL your codes
and also this line
ini_set('display_errors',1);
and keep this line only on development server.
while on the production it should be changed to
ini_set('display_errors',0);
ini_set('log_errors',1);
By doing this you will not need Stackoverflow assistance in reading the now obvious error messages.
Change that second line to:
$fh = fopen("/my/path/to/file.txt", "r") or die($php_errormsg);
and see what it outputs as the cause.
Try to output system errors in die or try use try…catch. Also turn on php errors while development. Also check if file is readable before open it.
Most common issues are: file does not exists (or just incorrect path provided?), there is not enough permissions to read this file.
In your FTP file permissions tend to need to be 646 (or -rw-r--rw-), not 777 (always ignore those kind of comments). You want to give a key to someone you trust, setting permissions to 777 is like giving a copy of your key to everyone.
You should check that the specified file directory is inside the working directory. You can do this with 'getcwd'
echo getcwd();
If you still get the error, you should check the file permissions.
ls -l /my/path/to/file.txt
If you get this output "-rw-r--r--" you will see the file is writable for admin only.
To make the file writable for everyone use chmod command:
chmod 666 file.txt
You can check again with "ls -l", the z output should be "-rw-rw-rw-"
I am trying to read a video file uploaded on server using fopen and fread in php but fopen returns "unable to open file".
//test.php
<?php
$file=fopen("abc.mov","r") or exit("Unable to open file!");
?>
abc.mov exists in the same folder where test.php is located on the server i.e, at the same hierarchy.
I don't why it isn't able to read the file.
Please help.
This probably isn't a real problem with PHP or your file. This is most likely a problem with the permissions of the file. There are three things you can try here(probably more I don't know of). One, do this somewhere before the fopen in your script:
chmod("abc.mov", 0777);
Then echo fileperms(), just to check(take out after debug):
echo fileperms("abc.mov");
And lastly, before calling fopen, make sure that is_readable and file_exists return true:
if(file_exists("abc.mov") and is_readable("abc.mov")) {
$file = fopen("abc.mov","r") or exit("Unable to open file!");
}
else die("File isn't readable, or maybe doesn't even exist!");
Note: I would be using file_get_contents() and file_put_contents() rather than fopen.
Hope this helps!
Check your file access permissions to make sure you've got access to the file from PHP.