1.通常情况下,考虑到方便快捷,都是将图片上传到服务器,然后用数据库存储路径,再通过读取存储的路径来实现对图片的显示; 2.但有些特殊情况或项目要求可能需要php将上传图片以二进制保存到mysql数据库,无论如何,总归要知道些此方面的知识,所以才有了此篇博文; 3.百度上零零散散且年份久远的文章的code无法正常运行,然后本人几经周折,通过查阅资料、分析并多次实践才得以成功运行,希望对各位有所帮助。 注意:数据库中存储的图片越大,对数据库的性能影响越大,所以不推荐将图片数据存储进数据库。
文章目录
- 一、BLOB类型数据
- 二、数据库准备
- 三、图片存储
- 1. upimg.html(存储)
- 2. upimg.php(存储)
- 3. demo(存储)
- 四、图片读取
- 1. getimg.html(读取)
- 2. getimg.php(读取)
- 3. demo(读取)
- 五、图片读取(ajax写法,IE不兼容)
- 六、图片读取(伪ajax写法,IE无忧)
- TEST 1:存储并读取gif
- TEST 2:删除 / 改动原图对读取无影响
- TEST 3:存储PDF文档
一、BLOB类型数据
- 图片文件是二进制数据,所以需要把二进制数据保存在mysql数据库。
- mysql数据库提供了BLOB类型用于存储大量数据,BLOB是一个二进制对象,能容纳不同大小的数据。
- BLOB类型有以下四种,除存储的最大信息量不同外,其他都是一样的。
BLOB类型 (建议选 longblob )
BLOB类型 | 大小(单位:字节) |
TinyBlob | 最大 255 |
Blob | 最大 65K |
MediumBlob | 最大 16M |
LongBlob | 最大 4G |
二、数据库准备
主要字段只有 binarydata(图片二进制流写入) 和 type(图片类型),id用来查询,其余字段可自设
1.cmd 操作建表(id主键无符号自增,binarydata为blob类型,type显示图片类型)
create table image(
id int(4) unsigned not null auto_increment,
binarydata longblob not null,
type varchar(50) not null,
primary key (id));
2. Navicat(数据表可视化工具)查看数据表
三、图片存储
1. upimg.html(存储)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form method="post" action="upimg.php" enctype="multipart/form-data">
<label for="userImg">选择需要存储的图片文件:</label><br />
<input type="file" name="userImg" /><br />
<input type="submit" name="sub" />
</form>
</body>
</html>
2. upimg.php(存储)
PS:
- 未实现去重,去重需设文件名字段,进行判断,但这里为了简洁,只设置必要字段;
- 未实现限制文件类型,也就是想要限制仅上传图片,需要自行编写判断
<?php
/*---数据库操作---*/
$dbhost = 'localhost'; //数据库服务器主机地址
$dbname = 'admin1'; //mysqli账号
$dbpass = 'admin1'; //mysqli密码
$database = 'admin1'; //需操作的数据库
//连接数据库
$conn = mysqli_connect($dbhost, $dbname, $dbpass, $database);
//设置字符编码,防止中文乱码
mysqli_query($conn, 'set names utf8');
mysqli_query($conn, 'set character set utf8');
//判断是否连接失败
if(!$conn) {die('admin1库连接失败:'.mysqli_error($conn));}
/*--图片存储进mysql部分---*/
$img = $_FILES['userImg']; //获取file(文件)
if (isset($_POST['sub'])) { //表单提交成功则执行
//二进制读取操作
$b_data = addslashes(fread(fopen($img['tmp_name'], "r"), filesize($img['tmp_name'])));
//sql语句进行存储
$sql = 'INSERT INTO image (binarydata,type)'.
'VALUES'.
'("'.$b_data.'", "'.$img['type'].'");';
//执行sql
$retval = mysqli_query($conn, $sql);
//判断sql是否执行成功
if (!$retval) {
die('存储失败:'.mysqli_error($conn));
} else {
echo "图片已存储到数据库!";
}
}
?>
3. demo(存储)
四、图片读取
1. getimg.html(读取)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script>
window.onload = function() {
var str = document.getElementById('str');
var btn = document.getElementById('btn');
var img = document.getElementById('demo');
str.focus(); //聚焦
//js控制img
btn.onclick = function() {
img.alt = '图片不存在,载入失败...';
img.style.background = 'gainsboro';
img.setAttribute('width','200px');
//img.setAttribute('height','200px'); //高自适应,不固定死
img.src = 'getimg.php?id='+str.value;
//通过控制路径,传入参数 ?id=值 即可获取图片
//参数为 php 的参数 $_GET['id'] ,注意对接
str.value = ''; //清空输入框
str.focus(); //聚焦
}
}
</script>
</head>
<body>
<div>
<h4>请输入需要获取的图片id:</h4>
<input type="text" id="str" />
<input type="button" id="btn" value="确认" />
</div>
<div>
<img id="demo" />
</div>
</body>
</html>
2. getimg.php(读取)
<?php
/*---数据库操作---*/
$dbhost = 'localhost'; //数据库服务器主机地址
$dbname = 'admin1'; //mysqli账号
$dbpass = 'admin1'; //mysqli密码
$database = 'admin1'; //需操作的数据库
//连接数据库
$conn = mysqli_connect($dbhost, $dbname, $dbpass, $database);
//设置字符编码,防止中文乱码
mysqli_query($conn, 'set names utf8');
mysqli_query($conn, 'set character set utf8');
//判断是否连接失败
if(!$conn) {die('admin1库连接失败:'.mysqli_error($conn));}
/*---图片从mysql中读取---*/
# $_GET['id'] = 1; //用于测试
$id = $_GET['id'];
//sql语句
$sql = 'select binarydata, type from image where id='.$id;
$retval = mysqli_query($conn, $sql); //执行sql
//将查询得到的行,作为数组形式,输出列
$row = mysqli_fetch_array($retval);
# echo isset($row['binarydata']); //检测binarydata是否有值
# echo isset($row['type']); //检测type是否有值
//向客户端发送原始的HTTP报头(最重要的部分)
header('Content-type: '.$row['type']); //等于本身类型,不设定会乱码
//清空输出缓冲区的内容,防止php将utf8的bom头输出
ob_clean();
//直接输出longblob字段的内容
echo $row['binarydata']; //大小通过js调整
?>
3. demo(读取)
五、图片读取(ajax写法,IE不兼容)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script>
window.onload = function() {
var str = document.getElementById('str');
var btn = document.getElementById('btn');
var img = document.getElementById('demo');
btn.onclick = function() {
//ajax
var request;
if (window.XMLHttpRequest) {
request = new XMLHttpRequest();
} else {
request = new ActiveXObject('Microsoft.XMLHTTP');
}
request.responseType = 'blob';
request.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
//HTML5 URL静态方法
var blob = this.response;
img.src = window.URL.createObjectURL(blob);
//URL.createObjectURL() 方法生成应用 File 或 Blob 对象的 url
img.onload = function(e) {
//释放由 URL.createObjectURL() 创建的 URL 对象
window.URL.revokeObjectURL(img.src);
}
showImg(); //记得调用函数
}
};
request.open('GET', 'getimg.php?id='+str.value, true);
request.send(null);
}
//定义显示图片的函数
function showImg() {
img.alt = '图片不存在,载入失败...';
img.style.background = 'gainsboro';
img.setAttribute('width','200px');
//img.setAttribute('height','200px'); //高自适应,不固定死
str.value = ''; //清空输入框
str.focus(); //聚焦
}
str.focus(); //聚焦
}
</script>
</head>
<body>
<div>
<h4>请输入需要获取的图片id:</h4>
<input type="text" id="str" />
<input type="button" id="btn" value="确认" />
</div>
<div>
<img id="demo" />
</div>
</body>
</html>
六、图片读取(伪ajax写法,IE无忧)
PS:为何说伪ajax?其实就是第一种方法修改了下,即设置 img 的 src 而已,获取 img 路径(路径为 php 读取的存储在 mysql 的二进制数据),把 ajax 东西去掉就是第一种写法了,还不如直接用第一种非ajax好。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script>
window.onload = function() {
var str = document.getElementById('str');
var btn = document.getElementById('btn');
var img = document.getElementById('demo');
btn.onclick = function() {
//ajax
var request;
if (window.XMLHttpRequest) {
request = new XMLHttpRequest();
} else {
request = new ActiveXObject('Microsoft.XMLHTTP');
}
//request.responseType = 'blob'; 这里不需要
request.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
//为了区别另一种ajax写法,src 我写在这了,也就是区别就在这,还有不需要 'blob'
img.src = 'getimg.php?id='+str.value;
showImg(); //记得调用函数
}
};
request.open('GET', 'getimg.php', true); //php参数在 src 设置
request.send(null);
}
//定义显示图片的函数
function showImg() {
img.alt = '图片不存在,载入失败...';
img.style.background = 'gainsboro';
img.setAttribute('width','200px');
//img.setAttribute('height','200px'); //高自适应,不固定死
str.value = ''; //清空输入框
str.focus(); //聚焦
}
str.focus(); //聚焦
}
</script>
</head>
<body>
<div>
<h4>请输入需要获取的图片id:</h4>
<input type="text" id="str" />
<input type="button" id="btn" value="确认" />
</div>
<div>
<img id="demo" />
</div>
</body>
</html>
TEST 1:存储并读取gif
TEST 2:删除 / 改动原图对读取无影响
PS:
- 存储图片路径的方法,路径下的图片更改,或改动图片路径,会影响读取(但是方便快捷,也是常用方法);
- 而这里是将图片数据存储进数据库,也就没有存储路径可言,只要不修改里面的数据,它是不会有问题的(当然,存储的图片越大,数据库性能越低,读取越慢)。
TEST 3:存储PDF文档
PS:
- 当然存储是能存,因为我没限制上传类型;但这里的code无法读取pdf,需要修改html和php。