This chapter reveals that you can use files and databases together to build PHP application that waash in binary data.

The application needs to store images.

Firstly, we should use the ALTER statement to change the structure of a database.

ALTER TABLE guitarwars
ADD COLUMN screeshot varchar(64)

Next step, we should understand how can we get an image from the user ?

<input type="file" id="screenshot" name="screenshot" />

This can use a file input field to allow image file uploads.

Then we should Insert the data posted from the form into the table, use the INSERT statment :

INSERT INTO guitarwars VALUES
(0, NOW(), '$name', '$score', '$screenshot') 

Here we just need to insert the filename into the table , so $screenshot represents the name of the file

the super variable $_FILES is where PHP stores infomation about an uploaded file.

$screenshot = $_FILES['screenshot']['name']
// some other attributes :
$_FILES['screenshot']['type']
$_FILES['screenshot']['size']
$_FILES['screenshot']['tmp_name']
$_FILES['screenshot']['error']

you may have a question why dont just store the image file into the database ?

Databases excel at storing text data, not raw binary data such as images. so its better to just store a reference to an image in the database .

This reference is the name of the image file.

Another reason is beacese it would be much harderto display them using HTML code. You can see that generating an image tag

in HTML involves using an image filename, not raw image data. just like :

<img src = "phizsscore.jpg" alt = "Score image" />

Here is another question, when we uploads the file, where did they go ?

The answer is the file is actually uploaded to a temporary folder on the server. The temporary folder is created automatically on the server

and usually has a weird name with a bunch of random letter and numbers.

If we want to use the files again, we should control the initial storage location of uploaded files in PHP.

You can move file from the temporary folder to a permanenet folder by using this function :

move_uploaded_file( $_FILES['screenshot']['name'], $target) ;

$target is the destination location where you want to put the file on server .

Every Application needs a image folder. so create a home for uploaded iamge files.

$target = GW_UPLOADPATH.$screenshot ;

There is another problem, if two users uploaded image file with the same filenames, it will overwrite the one before.

A simple way to solve this is to add current server time to the front of the filename:

$target = GW_UPLOADPATH. time() . $screenshot  

Just a tips here : If your PHP App is hosted anywhere other than your local computer, you'll need to use FTP to

create the images folder on the server.

If the path changes, you have to change the code in all places, so you can use define() to avoid this :

define('GW_UPLOADPATH', 'images/')

and if you want to access the constants in other scripts, you may use the require_once()

require_once('appvars.php');

Just think of require_onece as "insert" . This statement inserts shared script code into other scripts.

We almost finish our application. But if this would be a real appliaction, is needs the VALIDATION .

Validation on the image file serves two vitial purposes. 1, it can beef up the prevention of large file uploads, providing users with notification that

a file cant be larger than 32kb. 2, it can stop people from uploading files that aren't images. try the code below: 

if (
( ($screenshot_type == 'image/gif') || ($screenshot_type=='image/jpeg')
||($screenshot_type == 'image/pjpeg') || ($screenshot_type == 'image/png'))
&& ($screenshot_size > 0) && ($screenshot_size <= GW_MAXFILESIZE)
) {
...
}

IN the real application, we often need some function groups and pages which can only be used by the admin, so the administrator

can manage this application. We will add an admin model in this app too.  

The project files are as follows :

/****      index.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 - High Scores</title>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<h2>Guitar Wars - High Scores</h2>
<p>Welcome, Guitar Warrior, do you have what it takes to crack the high score list? If so, just <a href="addscore.php">add your own score</a>.</p>
<hr /> <?php
require_once('appvars.php');
require_once('connectvars.php'); // Connect to the database
$dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); // Retrieve the score data from MySQL
$query = "SELECT * FROM guitarwars ORDER BY score DESC, date ASC";
$data = mysqli_query($dbc, $query); // Loop through the array of score data, formatting it as HTML
echo '<table>';
$i = 0;
while ($row = mysqli_fetch_array($data)) {
// Display the score data
if ($i == 0) {
echo '<tr><td colspan="2" class="topscoreheader">Top Score: ' . $row['score'] . '</td></tr>';
}
echo '<tr><td class="scoreinfo">';
echo '<span class="score">' . $row['score'] . '</span><br />';
echo '<strong>Name:</strong> ' . $row['name'] . '<br />';
echo '<strong>Date:</strong> ' . $row['date'] . '</td>';
if (is_file(GW_UPLOADPATH . $row['screenshot']) && filesize(GW_UPLOADPATH . $row['screenshot']) > 0) {
echo '<td><img src="' . GW_UPLOADPATH . $row['screenshot'] . '" alt="Score image" /></td></tr>';
}
else {
echo '<td><img src="' . GW_UPLOADPATH . 'unverified.gif' . '" alt="Unverified score" /></td></tr>';
}
$i++;
}
echo '</table>'; mysqli_close($dbc);
?> </body>
</html>

/****      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'];
$screenshot_type = $_FILES['screenshot']['type'];
$screenshot_size = $_FILES['screenshot']['size']; if (!empty($name) && !empty($score) && !empty($screenshot)) {
if ((($screenshot_type == 'image/gif') || ($screenshot_type == 'image/jpeg') || ($screenshot_type == 'image/pjpeg') || ($screenshot_type == 'image/png'))
&& ($screenshot_size > 0) && ($screenshot_size <= GW_MAXFILESIZE)) {
if ($_FILES['screenshot']['error'] == 0) {
// Move the file to the target upload folder
$target = GW_UPLOADPATH . $screenshot;
if (move_uploaded_file($_FILES['screenshot']['tmp_name'], $target)) {
// Connect to the database
$dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); // Write the data to the database
$query = "INSERT INTO guitarwars VALUES (0, NOW(), '$name', '$score', '$screenshot')";
mysqli_query($dbc, $query); // Confirm success with the user
echo '<p>Thanks for adding your new high score! It will be reviewed and added to the high score list as soon as possible.</p>';
echo '<p><strong>Name:</strong> ' . $name . '<br />';
echo '<strong>Score:</strong> ' . $score . '<br />';
echo '<img src="' . GW_UPLOADPATH . $screenshot . '" alt="Score image" /></p>';
echo '<p><a href="index.php">&lt;&lt; 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">Sorry, there was a problem uploading your screen shot image.</p>';
}
}
}
else {
echo '<p class="error">The screen shot must be a GIF, JPEG, or PNG image file no greater than ' . (GW_MAXFILESIZE / 1024) . ' KB in size.</p>';
} // Try to delete the temporary screen shot image file
@unlink($_FILES['screenshot']['tmp_name']);
}
else {
echo '<p class="error">Please enter all of the information to add your high score.</p>';
}
}
?> <hr />
<form enctype="multipart/form-data" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<input type="hidden" name="MAX_FILE_SIZE" value="<?php echo GW_MAXFILESIZE; ?>" />
<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="screenshot">Screen shot:</label>
<input type="file" id="screenshot" name="screenshot" />
<hr />
<input type="submit" value="Add" name="submit" />
</form>
</body>
</html>

/****      appvars.php    ****/

<?php
// Define application constants
define('GW_UPLOADPATH', 'images/');
define('GW_MAXFILESIZE', 32768); // 32 KB
?>

/****      connectvars.php    ****/

<?php
// Define database connection constants
define('DB_HOST', 'localhost');
define('DB_USER', 'root');
define('DB_PASSWORD', 'root');
define('DB_NAME', 'gwdb');
?>

About the adminuser, you can visit the admin model by : localhost/...path/guitarwars/admin.php

/****     admin.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 - High Scores Administration</title>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<h2>Guitar Wars - High Scores Administration</h2>
<p>Below is a list of all Guitar Wars high scores. Use this page to remove scores as needed.</p>
<hr /> <?php
require_once('appvars.php');
require_once('connectvars.php'); // Connect to the database
$dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); // Retrieve the score data from MySQL
$query = "SELECT * FROM guitarwars ORDER BY score DESC, date ASC";
$data = mysqli_query($dbc, $query); // Loop through the array of score data, formatting it as HTML
echo '<table>';
while ($row = mysqli_fetch_array($data)) {
// Display the score data
echo '<tr class="scorerow"><td><strong>' . $row['name'] . '</strong></td>';
echo '<td>' . $row['date'] . '</td>';
echo '<td>' . $row['score'] . '</td>';
echo '<td><a href="removescore.php?id=' . $row['id'] . '&amp;date=' . $row['date'] .
'&amp;name=' . $row['name'] . '&amp;score=' . $row['score'] .
'&amp;screenshot=' . $row['screenshot'] . '">Remove</a></td></tr>';
}
echo '</table>'; mysqli_close($dbc);
?> </body>
</html>

/****     removescore.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 - Remove a High Score</title>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<h2>Guitar Wars - Remove a High Score</h2> <?php
require_once('appvars.php');
require_once('connectvars.php'); if (isset($_GET['id']) && isset($_GET['date']) && isset($_GET['name']) && isset($_GET['score']) && isset($_GET['screenshot'])) {
// Grab the score data from the GET
$id = $_GET['id'];
$date = $_GET['date'];
$name = $_GET['name'];
$score = $_GET['score'];
$screenshot = $_GET['screenshot'];
}
else if (isset($_POST['id']) && isset($_POST['name']) && isset($_POST['score'])) {
// Grab the score data from the POST
$id = $_POST['id'];
$name = $_POST['name'];
$score = $_POST['score'];
}
else {
echo '<p class="error">Sorry, no high score was specified for removal.</p>';
} if (isset($_POST['submit'])) {
if ($_POST['confirm'] == 'Yes') {
// Delete the screen shot image file from the server
@unlink(GW_UPLOADPATH . $screenshot); // Connect to the database
$dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); // Delete the score data from the database
$query = "DELETE FROM guitarwars WHERE id = $id LIMIT 1";
mysqli_query($dbc, $query);
mysqli_close($dbc); // Confirm success with the user
echo '<p>The high score of ' . $score . ' for ' . $name . ' was successfully removed.';
}
else {
echo '<p class="error">The high score was not removed.</p>';
}
}
else if (isset($id) && isset($name) && isset($date) && isset($score)) {
echo '<p>Are you sure you want to delete the following high score?</p>';
echo '<p><strong>Name: </strong>' . $name . '<br /><strong>Date: </strong>' . $date .
'<br /><strong>Score: </strong>' . $score . '</p>';
echo '<form method="post" action="removescore.php">';
echo '<input type="radio" name="confirm" value="Yes" /> Yes ';
echo '<input type="radio" name="confirm" value="No" checked="checked" /> No <br />';
echo '<input type="submit" value="Submit" name="submit" />';
echo '<input type="hidden" name="id" value="' . $id . '" />';
echo '<input type="hidden" name="name" value="' . $name . '" />';
echo '<input type="hidden" name="score" value="' . $score . '" />';
echo '</form>';
} echo '<p><a href="admin.php">&lt;&lt; Back to admin page</a></p>';
?> </body>
</html>

At last, some css styles :

.error {
font-weight: bold;
color: #FF0000;
} .topscoreheader {
text-align: center;
font-size: 200%;
background-color: #36407F;
color: #FFFFFF;
} .score {
font-size:150%;
color: #36407F;
} .scoreinfo {
vertical-align: top;
padding-right:15px;
}

  

#3 working with data stored in files && securing your application的更多相关文章

  1. #3 working with data stored in files && securing your application (PART II)

    Security problems is more and more important on the internet today. You can see the problems . This ...

  2. Enabling granular discretionary access control for data stored in a cloud computing environment

    Enabling discretionary data access control in a cloud computing environment can begin with the obtai ...

  3. 安装mysql时出现initialize specified but the data directory has files in in.Aborting.该如何解决

    eclipse中写入sql插入语句时,navicat中显示的出现乱码(???). 在修改eclipse工作空间编码.navicate中的数据库编码.mysql中my.ini中的配置之后还是出现乱码. ...

  4. The multi-part request contained parameter data (excluding uploaded files) that exceeded the limit for maxPostSize set on the associated connector.

    springboot 表单体积过大时报错: The multi-part request contained parameter data (excluding uploaded files) tha ...

  5. Springboot 上传报错: Failed to parse multipart servlet request; nested exception is java.lang.IllegalStateException: The multi-part request contained parameter data (excluding uploaded files) that exceede

    Failed to parse multipart servlet request; nested exception is java.lang.IllegalStateException: The ...

  6. MYSQL常见安装错误集:[ERROR] --initialize specified but the data directory has files in it. Abort

    1.[ERROR] --initialize specified but the data directory has files in it. Abort [错误] -初始化指定,但数据目录中有文件 ...

  7. 启动MySQL5.7时报错:initialize specified but the data directory has files in it. Aborting.

    启动MySQL5.7时报错:initialize specified but the data directory has files in it. Aborting 解决方法: vim /etc/m ...

  8. Data caching per request in Owin application

    Data caching per request in Owin application 解答1 Finally I found OwinRequestScopeContext. Very simpl ...

  9. Fast data loading from files to R

    Recently we were building a Shiny App in which we had to load data from a very large dataframe. It w ...

随机推荐

  1. Android 浮动按钮的伸缩效果

    在做项目时想增加点动感,于是就有如下效果: 实现起来也很简单,通过属性动画和recyclerview 滑动结合就很好实现了. 通过给recycleview添加一个滑动监听:通过滚动的差值来处理动画 m ...

  2. Linux、命令ps 各字段意思

    参数: -A :所有的进程均显示出来,与 -e 具有同样的效用: -a : 显示现行终端机下的所有进程,包括其他用户的进程: -u :以用户为主的进程状态 : x :通常与 a 这个参数一起使用,可列 ...

  3. Check Point R80 Security Management

    平台: CentOS 类型: 虚拟机镜像 软件包: Security Management basic software security 服务优惠价: 按服务商许可协议 云服务器费用:查看费用 立即 ...

  4. jqGrid中multiselect: true 操作checkbox

    在jqGrid中设置multiselect: true可以实现全选的操作,但怎么设置被选中的checkbox里面的值呢,做法如下:jQuery("#listTable").jqGr ...

  5. 定时器new Timer().schedule()的使用

    Timer是一种工具,线程用其安排以后在后台线程中执行的任务.可安排任务执行一次,或者定期重复执行.实际上是个线程,定时调度所拥有的TimerTasks. TimerTask是一个抽象类,它的子类由 ...

  6. jenkins代码自动部署

    jenkins是一个广泛用于持续构建的可视化web工具,持续构建说得更直白点,就是各种项目的"自动化"编译.打包.分发部署.jenkins可以很好的支持各种语言(比如:java, ...

  7. HBuilder发行App(Android和ios)

    怎样将开发好的app测试和上架,此文包括Android和ios打包.测试和上架的大概过程.内容有些简陋,因为此过程踏坑无数,特此留念. 特此声明:内容不全仅供参考. 介绍两个参考网站: 1. http ...

  8. 【BZOJ1088】[SCOI2005] 扫雷Mine(分类讨论)

    点此看题面 大致题意: 给你一个\(2*n\)的扫雷棋盘,现让你根据第二列的信息确定第一列有多少种摆法. 扫雷性质 听说这是一道动态规划+数学题. 其实,根据扫雷游戏的某个性质,只要确定了第一个格子是 ...

  9. 浅谈 import / export

    import { ngModule } from '@angular/core'; import { AppComponent } from './app.component'; export cla ...

  10. solr 近实时搜索

    摘要: Solr的近实时搜索NRT(Near Real Time Searching)意味着文档可以在索引以后马上可以被查询到. Solr不会因为本次提交而阻塞更新操作,不会等待后台合并操作(merg ...