views:

298

answers:

5

I tried to open a file with fopen() function in PHP and it output warning of failure to open stream: permission denied. You know that warning / error you encounter when apache doesn't have enough privileges to open a particular file.

However despite the warning message being displayed, my PHP script successfully opened the file and wrote a string into it. It doesn't make sense.

So what is matter? I can put a @ immediately before fopen() but still it's weird and I want to know why PHP behaves this way. Is there something I didn't configure right?

class XMLDB {

    private $file = null;
    private $xml = null;
    private $defs = array();
    private $recs = array();

    // private members above, public members below

    public function __construct($xmlfile) {
     if (!file_exists($xmlfile)) {
      die('XML file does not exist.');
     }
     $this -> file = $xmlfile;
     $this -> xml = simplexml_load_file($this -> file);
     $this -> iniVocab();
     $this -> iniData();
    }

... /* lots of private and public functions */

    public function commit() {
     $xmlfile = fopen($this -> file, 'w'); // this is causing the warning
     $doc = new DOMDocument('1.0');
     $doc -> preserveWhiteSpace = false;
     $doc -> loadXML($this -> xml -> asXML());
     $doc -> formatOutput = true;
     fwrite($xmlfile, $doc->saveXML());
    }

    public function __destruct() {
     $this -> commit();
     /* comment this line out and there won't be any warnings, 
     /* therefore it should trace back to here. So I found out that
     /* it's when I use die() that eventually calls __destruct()
     /* which in turn calls commit() to trigger this fopen warning. */
    }
}

EDIT: So every first time I try to write something to the opened file, it's all right. Then if the class tries to commit all changes to the file again when the page is unloaded, that is, the object to be destroyed, it calls the __destruct() method and $this -> commit() to write the changes to the file - this is when the error occurs and it refuses to write to the file and pomping out the permission denied message. It's weird.

A: 

set the permission to 777 of that directory in which your file that you want to open resides.

Tareq
never ever use 777!.
Cem Kalyoncu
@Cem Kalyoncu: why? the apache process must be able to read it, and if anyone is going to read it it would be the apache process:)
Quamis
@Quamis: Well, if somebody got access to your system (no matter what user) that person can edit your file too some nasty kind of script and execute bad code on your system. Never set the permission to 777.
Morningcoffee
A: 

Are you sure you are getting this "permission denied" every time regardless of do this file exist or not? What is the folder permission this file resides at? You may have given read access to it, but not execute for example.

FractalizeR
A: 

Try using file_put_contents().... but i belive it would issue the same warnings...

Quamis
A: 

Does it give you the warning when you do that outside of __destruct? Might be something to do with that. Or apache has write permissions but not read?

Gus
+1  A: 

The problem may be that you forget to close your file with fclose.

Since you open the file, write stuff, and then try to open your already opened file. This might be the cause of the permission denial.

Morningcoffee
He's on to something here.
Chisum