move_uploaded_file给出“无法打开流:权限被拒绝”错误


143

当尝试在CentOS上使用Apache 2.2和PHP 5.3配置上传目录时,我一直收到此错误。

在php.ini中:

upload_tmp_dir = /var/www/html/mysite/tmp_file_upload/

在httpd.conf中:

Directory /var/www/html/mysite/tmp_file_upload/>
    Options  -Indexes
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>
<Directory /var/www/html/mysite/images/>
                Options -Indexes
</Directory>

CentOS目录权限:

drwxrwxr-x 2 root root 4096 Nov 11 10:01 images
drwxr-xr-x 2 root root 4096 Nov 12 04:54 tmp_file_upload

无论我做什么,上传文件时都会不断从PHP收到此错误:

警告:move_uploaded_file(images / robot.jpg):无法打开流:在/var/www/html/mysite/process.php的第78行,权限被拒绝

警告:move_uploaded_file():在第78行的/var/www/html/mysite/process.php中无法将'/ tmp / phpsKD2Qm'移动到'images / robot.jpg'

如您所见,它从未从php.ini文件中获取关于上传文件的配置。

我在这里做错了什么?


775?也许您的服务器没有人运行。在这种情况下,只有root用户才能写(您的“图像”权限)...
Konrad Borowski

这是什么意思 ?我该如何更改?
user63898

请记住,所有父目录也需要具有正确的权限。
Sridhar Sarnobat

Answers:


187

这是因为imagestmp_file_upload只能由root用户写入。为了使上传正常工作,我们需要使这些文件夹的所有者与httpd进程所有者相同,或者使它们在全局范围内可写(不好的做法)。

  1. 检查apache进程所有者:$ps aux | grep httpd。第一列通常是所有者nobody
  2. 更改您的所有者imagestmp_file_upload要成为的所有者,nobody或更改您在步骤1中找到的所有者。

    $sudo chown nobody /var/www/html/mysite/images/
    
    $sudo chown nobody /var/www/html/mysite/tmp_file_upload/
    
  3. Chmod imagestmp_file_upload现在可以由所有者写(如果需要的话)[似乎您已经准备好了。在@Dmitry Teplyakov答案中提及。

    $ sudo chmod -R 0755 /var/www/html/mysite/images/
    
    $ sudo chmod -R 0755 /var/www/html/mysite/tmp_file_upload/
    
  4. 有关发生此行为的原因的更多详细信息,请查看手册http://php.net/manual/zh-cn/ini.core.php#ini.upload-tmp-dir,请注意,它也涉及open_basedir指令。


4
谢谢:我们的老主人曾经是守护进程,现在是apache
zzapper 2013年

此修复适用于您可能将服务器php类型从fast_CGI,CGI更改为Apache_mod(如plesk等)的情况。可以继续使用原始用户的权限而不是Apache。这解决了我的问题。
elliotrock 2014年

1
我遇到了同样的错误,但是进程和文件夹都归jacob我所有(因为它是我的本地计算机),并且文件夹都具有755775
limeandcoconut 2015年

sudo service httpd restart更改权限后,我必须重新启动apache进程。然后它起作用了:)chown我没有更改所有者,而是将我的apache进程添加到了“ www”组,并通过以下方式将这些目录添加到了相同的“ www”组中chgrp
Ali Saeed 2015年

76

您还可以运行以下脚本来查找Apache进程所有者:

<?php echo exec('whoami'); ?>

然后将目标目录的所有者更改为您拥有的目录。使用命令:

chown user destination_dir

然后使用命令

chmod 755 destination_dir

更改目标目录权限。


3
谢谢,对我有用。我首先使用了Laith Shadeed的方法,但键入ps aux |时却没有得到相同的结果grep httpd<?php echo exec('whoami'); ?>。有人知道为什么吗?
kukinsula 2014年

1
ps aux | grep https不返回Web服务器所有者名称。这是:ps aux | grep -E'[a] pache | [h] ttpd | [_] www | [w] ww-data | [n] ginx'| grep -v根| 头-1 | 切-d \ -f1 Fron Symfony文档。
David Jacquel 2014年

1
注意,在上面的命令中,“-d \”和“ -f1”之间应该有两个空格。如果按原样复制粘贴,则可能会出现类似“ cut:bad delimiter”的错误。
Beejor 2015年

1
加上1 exec('whoami')。为我节省了30分钟。正在向ubuntu用户扔
Deval Khandelwal

11
应该是www-data吗?通常
maxisme 2015年

18

如果您使用的是Mac OS X,请转到文件根目录或网站的文件夹。

然后右击它,获取信息,移至最底部(共享和权限),打开该窗口,将所有只读更改为读写。确保打开挂锁,转到设置图标,然后选择“ 应用于随附的项目...”。


当他的问题与Linux系统有关时,为什么要在Mac OS上发表评论?
Kmeixner '16

7
嗨,霍卡,谢谢您的回复。我在Mac上,您的答案解决了我的问题。非常感谢。
桑杰·夏尔马

2
喜欢这个答案
Alexey Sh。

2
@Kmeixner这个关于Linux的问题,但是在OSX上却完全一样。感谢这个评论它为我工作后,我的文件夹中改变了写选项/private/var/tmp在我的Mac。
萨拉姆

这是一篇较旧的文章,但这正是我需要做的。感谢
TheRobQ

14

这对我有用。

sudo adduser <username> www-data
sudo chown -R www-data:www-data /var/www
sudo chmod -R g+rwX /var/www

然后注销或重新启动。

如果有SELinux投诉,请尝试以下方法

sudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/www(/.*)?'
sudo restorecon -Rv '/var/www(/.*)?'

挽救了我的生命:) ..我使用GIT接收后钩子部署我的Web,每次部署时,我都会得到他的权限被拒绝的错误,将git用户添加到了固定的www-data中:)谢谢
Zalaboza

这是最好的答案。
saviour123 '17

12

我想将此添加到以前的建议中。如果您使用的是启用了SELinux的Linux版本,则还应该在shell中执行此操作:

chcon -R --type httpd_sys_rw_content_t /path/to/your/directory

通过组或更改目录所有者来为您的Web服务器用户授予权限。


restorecon -R -v /path/to/your/directory此后可能还需要包括在内。access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/...
AbsoluteƵERØ

可能非常正确,但是我假设chcon是“更改上下文”,即它刚刚被更改。您正在查看的内容首先使用“ semanage fcontext”,它将其放入某些设置文件“ file_contexts.local”中,但是它永远不会更改上下文。
克里斯(Chris

@克里斯,谢谢你。这解决了我的问题。您能说明一下这件事吗?该命令实际上是做什么的?我浏览了手册页,甚至是chcon的信息,都没有找到您输入的类型的值。我在这里有点困惑。
小丑

它使目录或文件可被Web服务器(httpd)读取...老实说,我不想也可能无法解释selinux,因为我本人对此几乎一无所知 ...请参阅nsa.gov/what-we-do / research / selinux / documentationaccess.redhat.com/documentation/en-us/red_hat_enterprise_linux/…–
克里斯(Chris


7

试试这个:

  1. 打开/ etc / apache2 / envvars

    sudo gedit /etc/apache2/envvars
  2. 更换www-data你的your_username

    "export APACHE_RUN_USER=www-data" 

    用。。。来代替

    export APACHE_RUN_USER='your_username' 

7

即使已经成功运行composer,我也遇到了这个相关问题。我更新了作曲家,并且在运行时composer install还是php composer.phar install得到了:

...无法打开流:权限被拒绝...

经过大量研究,结果表明,先前有关更改文件夹权限的答案有效。现在它们只是稍微不同的目录。

在我的OS X上的安装中,缓存文件位于中/Users/[USER]/.composer/cache,并且由于缓存文件由root拥有,因此出现了问题。以递归方式向我的用户更改“ .composer”的所有权解决了该问题。

这是我所做的:

sudo chown -R [USER] cache

然后我再次运行作曲家安装,瞧!


5

当apache用户(www-data)没有写文件夹中的权限时,会发生此问题。要解决此问题,您需要将用户放入组www-data中。

我刚刚做了这个:

执行此php代码<?php echo exec('whoami'); ?>以发现apache使用的用户。之后,在终端中执行命令:

user@machine:/# cd /var/www/html

user@machine:/var/www/html# ls -l

它将返回如下内容:

total of files

drwxr-xr-x 7 user group size date folder

我保留了该用户,但将该组更改为www-data

chown -R user:www-data yourprojectfoldername

chmod 775 yourprojectfoldername

4

解决方案是如此简单。仅右键单击IMAGE(目标)文件夹,转到属性,单击权限选项卡,然后将其他访问权限更改为创建和删除文件


但是最快的方法,只有您使用GUI进行FTP
传输

3

只需将tmp_file_upload的权限更改为755,以下是命令chmod -R 755 tmp_file_upload


2

试试这个

find /var/www/html/mysite/images/ -type f -print0 | xargs -0 chmod -v 664


得到:chmod:664后缺少操作数
user63898
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.