最近在学习《HeadFirst PHP & MySQL》一书的第5章“使用存储在文件中的数据”,做一个文件上传的应用时,出现了错误,就是文件无法成功上传。这个问题困扰了我很久,不过还好最后终于解决了。原因是我上传的图片文件大小超过了HTML 表单中MAX_FILE_SIZE 选项指定的值32768Bytes即32KB导致无法上传成功。

我使用了XAMPP(Apache + MySQL + PHP + Perl)集成开发包和Zend
Studio 10.6
作为PHP IDE开发环境,另外关于PHP调试我采用了XDebug,在Zend Studio10.6中配置Xdebug的PHP调试环境我参考了博文Zend Studio 10.5 与 XDebug 调试| Zend Debugger 说明 Drupal 源代码 (一)一文。

相应的文件上传示例PHP代码addscore.php如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Guitar Wars - Add Your High Score</title>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<h2>Guitar Wars - Add Your High Score</h2> <?php
require_once 'appvars.php';
require_once 'connectvars.php'; if (isset($_POST['submit'])) {
// Grab the score data from the POST
$name = $_POST['name'];
$score = $_POST['score'];
$screenshot = $_FILES['screenshot']['name']; if (!empty($name) && !empty($score) && !empty($screenshot)) {
// Move the file to the target upload folder
$target = GW_UPLOADPATH . $screenshot;
echo json_encode($_FILES); if (move_uploaded_file($_FILES['screenshot']['tmp_name'], $target)) {
// Connect to the database
$dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME)
or die('Error Connecting to MySQL Database!'); // Write the data to the database
$query = "INSERT INTO guitarwars VALUES (0, NOW(), '$name', '$score','$screenshot')";
mysqli_query($dbc, $query) or die('Error querying database;'); // Confirm success with the user
echo '<p>Thanks for adding your new high score!</p>';
echo '<p><strong>Name:</strong> ' . $name . '<br />';
echo '<strong>Score:</strong> ' . $score;
echo '<img src="' . GW_UPLOADPATH . $screenshot . '" alt="Score image" /></p>';
echo '<p><a href="index.php"><< Back to high scores</a></p>'; // Clear the score data to clear the form
$name = "";
$score = "";
$screenshot = ""; mysqli_close($dbc);
}
}
else {
echo '<p class="error">Please enter all of the information to add your high score.</p>';
}
}
?> <hr />
<form method="post" enctype="multipart/form-data" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<input type="hidden" name="MAX_FILE_SIZE" value="32768" />
<label for="name">Name:</label>
<input type="text" id="name" name="name" value="<?php if (!empty($name)) echo $name; ?>" /><br />
<label for="score">Score:</label>
<input type="text" id="score" name="score" value="<?php if (!empty($score)) echo $score; ?>" /><br />
<label for="screeshot">ScreenShot</label>
<input type="file" id="screenshot" name="screenshot" />
<hr />
<input type="submit" value="Add" name="submit" />
</form>
</body>
</html>

在使用Zend Sutdio10.6设置断点并调试上面这段PHP代码时我发现“if (move_uploaded_file($_FILES['screenshot']['tmp_name'], $target)) {”这行代码里面的代码块没有执行,于是查看了超全局变量$_FILES['screenshot']['tmp_name']的值为空,然后我在这行代码前以JSON格式打印出$_FILES变量的值,如下:

{"screenshot":{"name":"Penguins.jpg","type":"","tmp_name":"","error":2,"size":0}}

相应的运行截图如下:

然后我查询$_FILES['screenshot']['error']为2,上网查询了一下,关于$_FILES超级全局变量的介绍大体如下:

PHP编程语言中的常见的$_FILES系统函数用法有:
$_FILES['myFile']['name'] 显示客户端文件的原名称。
$_FILES['myFile']['type'] 文件的 MIME 类型,例如"image/gif"。
$_FILES['myFile']['size'] 已上传文件的大小,单位为字节。
$_FILES['myFile']['tmp_name'] 储存的临时文件名,一般是系统默认。
$_FILES['myFile']['error'] 该文件上传相关的错误代码。以下为不同代码代表的意思:
0:文件上传成功。
1:超过了文件大小php.ini中即系统设定的大小。
2:超过了文件大小
MAX_FILE_SIZE 选项指定的值。
3;:文件只有部分被上传。
4:没有文件被上传。
5:上传文件大小为0。

另外,查询PHP参考手册关于move_uploaded_file函数的介绍如下:

move_uploaded_file

(PHP 4 >= 4.0.3, PHP 5)

move_uploaded_file — 将上传的文件移动到新位置

说明

bool move_uploaded_file ( string $filename , string $destination )

本函数检查并确保由 filename 指定的文件是合法的上传文件(即通过 PHP 的 HTTP POST 上传机制所上传的)。如果文件合法,则将其移动为由 destination 指定的文件。 

这种检查显得格外重要,如果上传的文件有可能会造成对用户或本系统的其他用户显示其内容的话。 

参数

filename
上传的文件的文件名。
destination
移动文件到这个位置。 返回值 成功时返回 TRUE。 如果 filename 不是合法的上传文件,不会出现任何操作, move_uploaded_file() 将返回 FALSE。 如果 filename 是合法的上传文件,但出于某些原因无法移动,不会出现任何操作, move_uploaded_file() 将返回 FALSE。此外还会发出一条警告。

范例

Example #1 Uploading multiple files

<?php
$uploads_dir = '/uploads';
foreach ($_FILES["pictures"]["error"] as $key => $error) {
if ($error == UPLOAD_ERR_OK) {
$tmp_name = $_FILES["pictures"]["tmp_name"][$key];
$name = $_FILES["pictures"]["name"][$key];
move_uploaded_file($tmp_name, "$uploads_dir/$name");
}
}
?>

原因终于找到了,是因为我上传了一个超过32768Bytes即32KB大小的Penguins.jpg文件导致出现$_FILES['screenshot']['error']为2的错误,并且$_FILES['screenshot']['tmp_name']为空,move_uploaded_file($_FILES['screenshot']['tmp_name'],
$target)函数调用时返回FALSE,if (move_uploaded_file($_FILES['screenshot']['tmp_name'], $target)) { 

  ...

 }代码块没有执行。

最新文章

  1. Taurus.MVC 2.0 开源发布:WebAPI开发教程
  2. 织梦(dedecms)系统常用全局变量调用标签及路径
  3. 我见过的几门语言中的hello world
  4. 【转】SQL注入(通过sqlmap来改变所有事情)
  5. iOS设计模式——单例模式
  6. Unity3DGUI:Window
  7. C++ 11 学习1:类型自动推导 auto和decltype
  8. VS2012启用angularjs智能提示Intelligence(转)
  9. 你应该学会的Postman用法
  10. 智能合约语言 Solidity 教程系列3 - 函数类型
  11. 听翁恺老师mooc笔记(9)--枚举
  12. MappedByteBuffer
  13. java web(六):mybatis之一对一、一对多、多对多映射
  14. ZigZag Conversion 之字形转换字符串
  15. Java 虚拟机面试题全面解析(干货)
  16. 【Android】Android开源项目精选(一)
  17. Redis:redis.conf配置
  18. [MySQL] 中 Schema和Database的区别
  19. 《第一本Docker书》
  20. 前端常见算法面试题之 - 二维数组中的查找[JavaScript解法]

热门文章

  1. JQuery判断radio(单选框)是否选中和获取选中值
  2. python学习笔记之数据类型、字符编码、文件处理
  3. Java并发AtomicIntegerArray类
  4. Cocos2d-x之UI控件简介
  5. bstToDoublyList
  6. 【异常】Caused by: java.lang.IllegalStateException: Method has too many Body parameters
  7. 【记录】logstash 命令解释
  8. 【记录】vue相关知识点
  9. APScheduler的简单记录
  10. jvm加载包名和类名相同的类的规则,以及如何加载包名和类名相同的类(转)