【问题标题】:PHP move_uploaded_file fails with no errorsPHP move_uploaded_file 失败且没有错误
【发布时间】:2020-09-16 14:42:24
【问题描述】:

在 LEMP(Linux CentOS、Nginx、MariaDB、PHP)服务器上,/etc/php.ini 文件有以下内容。

file_uploads = on
upload_tmp_dir = /tmp

Stage1.html 有如下标记,用于选择图片文件,并将图片发布到 Stage2.php。

<form action="Stage2.php" method="post" enctype="multipart/form-data">
    <input type="file" name="upload">
    <input type="submit">
</form>

Stage2.php 有以下内容。

<?php
    $original_name = $_FILES["upload"]["name"];
    $temporary_name = $_FILES["upload"]["tmp_name"];
    $target = "/var/www/html/images/" . $original_name;

    if(move_uploaded_file($temporary_name, $target)) {echo "Success";}
    else{echo "Failed";}
?>

原始文件、临时文件和目标已正确设置。但是,返回 Failed

将以下内容添加到Stage2.php返回0。引用PHP Manual,0表示“没有错误,文件上传成功。”

$_FILES["upload"]["error"];

将以下内容添加到 Stage2.php 不会显示任何错误。这让我怀疑 PHP 认为一切正常,也许问题出在 CentOS 或 Nginx 上。这是合乎逻辑的假设吗?

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

为了调试,在 CentOS 中,我将 /tmp 和 /var/www/html/images 的权限设置为 777(每个人都可以读取、写入、执行)。仍然没有返回错误。

【问题讨论】:

  • 检查你的 max_upload_file_size
  • upload_max_filesize 为 2 MB,上传的文件为 40 KB。
  • if(move_uploaded_file($original_name , $target)) 试试这个并检查@JeremyCanfield
  • if(move_uploaded_file($original_name, $target)) 也会产生 Failed,因为 move_uploaded_file 函数将临时文件移动到目标目录。

标签: php linux nginx


【解决方案1】:

以防万一其他人遇到这个问题,我想分享我的发现。我可以断定这是 Linux CentOS 的问题,而不是 PHP 的问题。

通常,open_basedir 将在 /etc/php.ini 中设置为 /var/www。在这种情况下,upload_tmp_dir 必须低于/var/www。我将upload_tmp_dir 设置为/var/www/html/images/tmp

upload_tmp_dir = /var/www/html/images/tmp

然后我设置临时上传目录权限为755。

[john.doe@server1 ~]# chmod 755 /var/www/html/uploads/tmp

然后我使用以下 PHP 来确定 PHP 使用什么用户来上传文件。在我的场景中,用户是 apache

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

确定用户是 apache 后,我将临时上传目录的所有者设置为 apache。

[john.doe@server1 ~]# chown apache:root /var/www/html/uploads/tmp

最后,我必须将临时和永久上传目录的 SELinux 上下文设置为 httpd_sys_rw_content_t

[john.doe@server1 ~]# chcon --type httpd_sys_rw_content_t /var/www/html/uploads
[john.doe@server1 ~]# chcon --type httpd_sys_rw_content_t /var/www/html/uploads/tmp

做完这些之后,我就可以使用 PHP 上传文件了。

【讨论】:

  • 仅供参考,我还需要chcon --type httpd_sys_rw_content_t /tmp
【解决方案2】:

在这种情况下,我可以成功上传文件! 只需在终端中运行以下命令

chcon -Rv --type=httpd_sys_rw_content_t /var/www/html/directoryPath

注意:操作系统 centOS 7,Apache2.4.6

【讨论】:

    猜你喜欢
    • 2013-01-17
    • 2012-10-08
    • 1970-01-01
    • 2019-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多