26

I am confused with this code:

test.php:

fopen('test.txt','a+');

when I execute it, I get an error:

Warning: fopen(test.txt): failed to open stream:
     Permission denied in /var/www/html/yuelu3/mobile/text.php on line 2

test.txt:

-rwxrwxrwx. 1 jt jt     87 10月  7 20:58 test.txt

where is the problem?

Thanks a lot!I have found the problem,I use FC13,because of the protect of SELinux,some action is denied.So, I just need to get rid of the protect.

T_t
  • 375
  • 1
  • 6
  • 12

10 Answers10

14

try

fopen('/path/to/file/test.txt','a+');

as

fopen('test.txt','a+');

is most likely looking in another directory

Phill Pafford
  • 83,471
  • 91
  • 263
  • 383
13

I have been receiving the same error "failed to open stream. permission denied"when trying to write a file on the server using PHP. I tried everything on the internet to fix the error. I changed ownership of the files,directories and sub-directories on the server to "apache", I did a chmod 777 on all the files, directories, sub-directories, I ran restorecon -R, I ran chcon unconfined_u:object_r:httpd_user_content_t:s0 on all the files, but the only thing that seemed to work is turning SELinux off completely.

I finally resolved the issue. The problem lay in the boolean parameters used by SELinux. I performed the following command to get a list of all the booleans related to httpd.

$ getsebool -a | grep httpd

This gave a list of about 36 parameters.

I painfully went and turned on every boolean using the setsebool command until the "failed to open stream. permission denied" error went away.

When I turned "on" the httpd_unified boolean, the error went away!! When I turned it "off", the error came back!!

moe asal
  • 750
  • 8
  • 24
kwatts
  • 127
  • 1
  • 7
  • Thank you very much. I just changed chmod of all directories and sub-directories to 777 and it worked fine for me! – Jahanzaib Asgher Nov 03 '16 at 07:40
  • 2
    and the command for that is: sudo setsebool -P httpd_unified 1 :) – Saint Mar 25 '19 at 18:01
  • if this was reddit, this would get a platinum – Petar Subotic Nov 25 '19 at 13:48
  • @JahanzaibAsgher turning folders to 777 is an overkill and unnecessary. this is SELinux issue as pointed out by __mistapink__. Simply tell SELinux to allow writing on the right directory - not turning the setting off. – Ajowi Dec 15 '21 at 12:22
  • In my case i tried to fopen a remote file, the solution was setsebool -P httpd_can_network_connect 1 - thank you for pointing me in the right direction (8 years later :) – MartijndeM Apr 26 '23 at 12:13
8

Use fopen($_SERVER['DOCUMENT_ROOT'].'test.txt','a+');

Ondrej Slinták
  • 31,386
  • 20
  • 94
  • 126
Warrior
  • 5,168
  • 12
  • 60
  • 87
4

Paths always cause issues when trying to open files. An easy way to avoid having any problems when you are attempting to open files is by checking what directory you are in, and where you are making the call to.

echo getcwd();

Create a simple PHP page and make a call print the current directory. Drop the PHP page into the same directory as the file, and it will tell you the correct path to the folder and then just add on the /filename.xxx.

Kyle
  • 763
  • 3
  • 9
  • 18
4

Check the SELinux context mode of the file to be sure it is set to: httpd_user_content_t

...If it's not, use:

chcon httpd_user_content_t test.txt

...to correct the problem.

vdbuilder
  • 12,254
  • 2
  • 25
  • 29
2

I'm using an Apache HTTP server v2.4, I think the following method will work for most people on linux:
first thing check who is the user running 'httpd'.
It is daemon in my case, and I'm not sure if it is the case for everybody. you can do so using:
ps -ef | grep 'httpd'

once you're sure that the user daemon is the owner of the process httpd, change the owner of the folder in which you want the permission to write to deamon

sudo chown daemon /path/to/folder

this will change only the user, the group of that directory remain unchanged. if you want the group also to be able to write, make sure that it has write permission

sudo chmod g+w /path/to/folder

2

In my case these steps helped me:

  • Verify the process user using this command ps -ef
  • Result could be:
UID        PID  PPID  C STIME TTY          TIME CMD
www-data    18     1  0 15:43 pts/0    00:00:00 apache2 -DFOREGROUND
  • Add www-data user as owner of /var/www/html/ folder
chown -R www-data:www-data /var/www/html/
JRichardsz
  • 14,356
  • 6
  • 59
  • 94
0

Worked perfectly in a Docker running some version of PHP, but when I switched to Xampp for a quick test (since MySQL actually out of the box runs faster in Xampp) it stopped working. So this solved the task, just including the actual path to the file. This is most likely just due to different environment variables that varies in different versions and settings.

$filepath =  __DIR__ . DIRECTORY_SEPARATOR;
$in = fopen($filepath . 'test.txt','a+');
K. Kilian Lindberg
  • 2,918
  • 23
  • 30
0

In my case the reason was: "0644" permission for the file instead of "0777" (after moving from another hosting).

Andrews32
  • 47
  • 1
  • 5