PHP move_uploaded_file() 错误?

46
我使用以下代码,在我的本地机器上成功上传文件。它在我的本地机器上显示“上传成功”。
// Upload file
$moved = move_uploaded_file($_FILES["file"]["tmp_name"], "images/" . "myFile.txt" );

if( $moved ) {
  echo "Successfully uploaded";         
} else {
  echo "Not uploaded";
}

然而,当我在我的在线服务器上使用此代码时,它无法上传文件,只显示消息“未上传”。

我该如何知道问题出在哪里,以及如何让用户看到实际的问题呢?


1
你的网站服务器上有images文件夹吗?该文件夹只读还是可写的? - gabe3886
1
因为FileZilla可以写入该目录,并不意味着您的Web服务器也可以写入。 - fabrik
2
不,你应该阅读错误信息并修复问题。 - Your Common Sense
2
“如何”是另一个问题,可以得到答案。但你必须明白一个非常基本的规则:没有错误信息,你就是盲、聋和哑的。你唯一的愿望和努力应该是获取错误信息。我说得清楚吗? - Your Common Sense
6
一个程序员不应该轻信别人的话,无论是客户还是 Stack Overflow 上的志愿者,甚至是自己。只有在错误提示信息中,程序员才能够信赖它。 - Your Common Sense
显示剩余3条评论
13个回答

77

将代码编辑为以下内容:

// Upload file
$moved = move_uploaded_file($_FILES["file"]["tmp_name"], "images/" . "myFile.txt" );

if( $moved ) {
  echo "Successfully uploaded";         
} else {
  echo "Not uploaded because of error #".$_FILES["file"]["error"];
}

上传文件时可能会遇到以下1至8的错误代码:

UPLOAD_ERR_INI_SIZE = 值:1;上传的文件超过了php.ini中的upload_max_filesize指令。

UPLOAD_ERR_FORM_SIZE = 值:2;上传的文件超过了HTML表单中指定的MAX_FILE_SIZE指令。

UPLOAD_ERR_PARTIAL = 值:3;上传的文件只有部分被上传。

UPLOAD_ERR_NO_FILE = 值:4;未上传任何文件。

UPLOAD_ERR_NO_TMP_DIR = 值:6;缺少临时文件夹。在PHP 5.0.3中引入。

UPLOAD_ERR_CANT_WRITE = 值:7;无法将文件写入磁盘。在PHP 5.1.0中引入。

UPLOAD_ERR_EXTENSION = 值:8;某个PHP扩展程序阻止了文件上传。PHP无法确定哪个扩展程序导致文件上传失败;使用phpinfo()查看已加载的扩展程序列表可能有所帮助。


错误5是什么? - Dan
@Dan 根据php手册错误5没有被记录。就我个人而言,我还没有遇到过它。 - Denver Chiwakira

44

试一下这个:

$upload_dir = $_SERVER['DOCUMENT_ROOT'] . '/images/';

if (is_dir($upload_dir) && is_writable($upload_dir)) {
    // do upload logic here
} else {
    echo 'Upload directory is not writable, or does not exist.';
}

这将立即标记任何文件权限错误。


2
上传目录不可写或不存在。如何解决,请解释一下? - Abdulla Sirajudeen
2
@SignoffTeamz 要么将上传目录设置为可写,要么在不存在时创建它。 - Martin Bean
Linux中的chmod/chown用于文件权限,但在Web开发教程中并没有涵盖足够多。我发现使用776(不是最佳实践,最好使用775)可以解决大多数权限问题。使用-R选项与chmod一起使用,以确保权限传递到目录和目录中的文件。如果使用apache2,则Chown应将www-data作为所有者组,您的用户名作为所有者。您应该将自己添加到用户组www-data中,以便在测试目的下继承服务器中该文件夹内的权限。 - N E Techno Tech Blog

38

检查 Web 服务器是否具有向 "images/" 目录写入的权限


我可以使用FileZilla手动上传文件到这个文件夹,这意味着它具有权限。还有其他可能性吗? - Awan
11
FileZilla不能证明Web服务器具有权限。Web服务器很可能运行在与您不同的用户下。为了确保它具有权限,只需将权限设置为777,然后进行测试。这应该能够证明是否存在权限问题或其他问题。 - Andrei Serdeliuc ॐ
当上传了两个2MB的文件但未上传5MB的文件时会发生什么情况?这两个文件都是PDF类型的文件。那么我该如何从服务器获取精确的错误信息,以便我们可以知道确切的问题所在。 - Bhavin Thummar
所以我已经检查了phpinfo函数,其中upload_max_filesize为2mb,所以我认为这可能是问题所在,因此我将增加文件大小并再次检查。 - Bhavin Thummar
FileZilla是一个FTP客户端,Web服务器是Apache正在运行的用户... whoami(); - Pablo Contreras

19

我如何知道问题出在哪里?

很简单。请参考 Web 服务器的错误日志。

我该如何将实际问题显示给用户呢?

绝对不要这样做。
一个普通用户将理解不了这个错误信息。
而且,恶意用户也不应该得到任何反馈,尤其是非常详细的错误消息。

只需显示一个道歉页面即可。

如果您无法访问服务器的错误日志,则任务会变得更加复杂。
有几种方法可以获取错误消息。

要在屏幕上显示错误消息,您可以将这些行添加到代码中:

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

或者创建自定义错误日志文件。

ini_set('log_errors',1);
ini_set('error_log','/absolute/path/tp/log_file');

还有其他的方法。
但你必须明白,如果没有实际的错误信息,你无法前进。在黑暗中盲目行动是很困难的。


2
在开发网站上显示错误是可以的。但并非总是能将错误重定向到日志文件中(例如,在共享主机上)。 - Pekka
@Pekka,我们现在正在谈论一个实时的问题。而且,老实说,这样的主机应该立即被放弃。 - Your Common Sense

7

move_uploaded_file()将返回:

  1. 如果文件名无效,则返回FALSE
  2. 如果Apache进程没有对源或目标目录的读写权限,则返回FALSE并在错误日志中发出警告

PHP错误日志

我的PHP错误日志位于:/var/log/httpd/error_log,其中包含以下错误:

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

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

move_uploaded_file()尝试将文件从临时目录移动到目标目录。当Apache进程尝试移动文件时,它无法读取临时目录或写入目标目录。

  1. 查找运行Apache(Web服务器)的用户 通过此命令检查运行Apache服务的用户:ps aux | grep httpd。第一列是用户名。

  2. 检查临时目录的读取权限:您可以通过在php页面中调用echo sys_get_tmp_dir();来查找临时目录的路径。然后在命令行中,输入ls -ld /tmp/temporary-dir,以查看Apache用户是否有读取权限。

  3. 检查目标目录的写入权限:输入ls -ld /var/www/html/destination-directory,以查看Apache用户是否有写入权限。

  4. 根据需要使用chownchgrp添加权限

  5. 使用sudo service httpd restart重新启动Apache


如何在Windows中检查用户? - Black
1
问题已经通过关键字“source”解决。看这里:“如果Apache进程没有对“源”或目标目录具有读/写权限,则move_uploaded_file()将返回FALSE并在错误日志中发出警告。”因此,仅为项目目录授予所有权限是不够的,还应该为源文件的位置授予所有权限。 - Hasan

2

您是否检查过文件是否已成功上传?可能您已超出了最大post_size或max_upload_filesize。当使用FileZilla登录时,您是以自己的身份复制文件的,而通过PHP编写此文件时,它来自运行Apache的用户(例如www-data),请尝试为图像设置chmod 755权限。


1

或者运行suexec,就再也不用改变权限了。


1
php.ini 中搜索 upload_max_filesizepost_max_size。我遇到了同样的问题,解决方法是将这些值更改为大于文件大小的值。

0
$uploadfile = $_SERVER['DOCUMENT_ROOT'].'/Thesis/images/';
$profic = uniqid(rand()).$_FILES["pic"]["name"]; 

if(is_uploaded_file($_FILES["pic"]["tmp_name"]))
{
    $moved = move_uploaded_file($_FILES["pic"]["tmp_name"], $uploadfile.$profic);
    if($moved)
    {
        echo "sucess";
    }
    else
    {
        echo 'failed';
    }
}

0
我遇到了一个非常晦涩和烦人的6号错误原因。 在玩弄一些NFS挂载卷后,上传开始失败了。 通过重新启动服务解决了问题。
systemctl restart php-fpm.service
systemctl restart httpd.service

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接