无法使用 PHP 上传文件?
Posted
技术标签:
【中文标题】无法使用 PHP 上传文件?【英文标题】:Cant upload a file using PHP? 【发布时间】:2014-07-10 23:41:36 【问题描述】:谁能看看我的代码?人们可以单击上传按钮上传一些文件,代码应该将其移动到新位置并保存。我通过上传图像文件对其进行了测试,但在我指定的文件夹中找不到该文件。我确定目录是正确的,因为我使用的目录是文件夹,它可以通向我希望它所在的文件夹。因为下面的目录有我的名字,所以我用“1”代替。提前谢谢!
我根据答案更改了代码,但它仍然给我返回错误: 警告:move_uploaded_file(/Users/angeloliiao/Documents/Screen.tiff):无法打开流:第 16 行 /usr/local/zend/apache2/htdocs/JuvoliciousProductViewer/5.php 中的权限被拒绝
警告:move_uploaded_file():无法将 '/usr/local/zend/tmp/phpdfCRD3' 移动到 /usr/local/zend/apache2/htdocs/JuvoliciousProductViewer 中的 '/Users/angelolio/Documents/Screen.tiff' /5.php 第 16 行
我尝试在终端上使用以下命令更改文件夹的权限:sudo chown -R 0755 /Users/angeloliiao/Documents.它跑了。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<form enctype="multipart/form-data" method="POST">
<input type="file" name="file" />
<input type="submit" name="submit" value="upload" />
</form>
<?php
if ($_FILES)
$name = $_FILES['file']['name'];
$temp = $_FILES['file']['tmp_name'];
$dir = "/Users/angeloliao/Documents/";
if (move_uploaded_file($temp,$dir.$name))
echo "File is valid, and was successfully uploaded.\n";
else
echo "Possible file upload attack!\n";
?>
</html>
【问题讨论】:
您没有进行任何错误检查。您的代码应该检查错误并报告它们。这样,您就有机会在此处发布之前诊断出问题。查看 PHP 部分 Handling File Uploads - 特别是关于错误的部分 - 并检查move_uploaded_file()
的返回值。
别忘了Documents/
后面的斜杠,还有很多东西要让它安全或避免错误
我还建议将其发布到单独的页面,然后重定向回以清除提交的数据,没有人喜欢多次上传,但这有点解释工作。
这真的很危险。您永远不应该使用提供的文件名称来存储在您的服务器上。相反,您应该使用某种随机数(可能是散列的)。根据您的 php.ini 设置(和文件权限),想象如果有人上传了一个名为“../../../usr/local/bin/php”的文件。然后他们可以用执行恶意代码的东西替换你的 php 解释器。
+ 点划线(目录遍历),听@PhpMyCoder
【参考方案1】:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<form enctype="multipart/form-data" method="POST">
<input type="file" name="file" />
<input type="submit" name="submit" value="upload" />
</form>
<?php
$name = $_FILES['file']['name'];
$temp = $_FILES['file']['tmp_name'];
$dir = "/Users/1/Documents/";
move_uploaded_file($temp,$dir.$name);
?>
</body>
应该是 _ 而不是 + 并且目录应该是带有斜杠的“Documents/”
【讨论】:
【参考方案2】:根据the PHP documentation,临时名称位于$_FILES['file']['tmp_name']
而不是$_FILES['file']['tmp+name']
。另外,做一个var_dump()
的$dir.$name
。如果您上传的文件是“image.jpg”,那么它将是/Users/1/Documentsimage.jpg
。注意缺少的斜线。
更改此设置将使您的代码正常工作,但它仍然不能处理所有可能的错误,也不安全!上传可能会失败。如果是这样,您将在 $_FILES['file']['error']
中找到错误代码 (the docs has a reference that lists them all)。您应该在移动临时文件之前检查上传是否成功(如果表单已经提交,您也应该只执行移动命令)。
此外,使用上传者提供的名称也不安全。考虑$_FILE['file']['name']
是否为../../../usr/local/bin/php
。然后上传者可以用恶意的可执行文件替换你的 PHP 解释器。这是危险的!永远不要相信用户输入!在这种情况下,最好的做法是随机生成一个不依赖于原始文件名的文件名(即不要只散列提供的文件名,因为如果两个人上传同名文件怎么办?)。
if($_POST['submit'] === 'upload') // only process form if it has been submitted
if($_FILES['file']['error'] !== UPLOAD_ERR_OK)
exit('There was an error uploading your file');
$uploads_dir = '/Users/1/Documents/';
$upload_name = sha1(mt_rand().microtime(true)); // you should actually pick
// something more unique
// (collisions are possible)
move_uploaded_file($FILES['file']['tmp_name'], $uploads_dir . $upload_name);
【讨论】:
◎PhpMyCoder 请参考我编辑的代码。它仍然无法正常工作,错误通知(权限被拒绝)。我试图更改文件夹权限,但它不起作用 @Angelo 再次查看我的代码并重新阅读我的答案。你还没有完全实现它。您更新的版本仍然存在漏洞。您需要为 apache 用户 chown 文件(通常是 www-data,但它取决于系统)。您可以通过访问 httpd.conf 进行检查。您也可以运行ps aux | grep '(httpd|apache)'
(假设您正在运行 apache)并检查用户。
感谢您的回答。我有另一个相关的问题。我现在正在使用 Zend 服务器,根据 httpd.conf 文件,apache 用户是“守护进程”。我现在正在自己的电脑上开发网站。我应该将上传的文件设置到哪个目录?从更安全和更好的实践角度来看。以上是关于无法使用 PHP 上传文件?的主要内容,如果未能解决你的问题,请参考以下文章
解决nginx和php使用ckfinder无法上传大文件的问题
解决nginx和php使用ckfinder无法上传大文件的问题