php 上传图片,一般都使用move_uploaded_file方法保存在服务器上。但如果一个网站有多台服务器,就需要把图片发布到所有的服务器上才能正常使用(使用图片服务器的除外)
如果把图片数据保存到数据库中,多台服务器间可以实现文件共享,节省空间。
保存在数据库,更重要的是一点安全!
首先图片文件是二进制数据,所以需要把二进制数据保存在mysql数据库。
mysql数据库提供了BLOB类型用于存储大量数据,BLOB是一个二进制对象,能容纳不同大小的数据。BLOB类型有以下四种,除存储的最大信息量不同外,其他都是一样的。可根据需要使用不同的类型。
TinyBlob 最大 255B Blob 最大 65K MediumBlob 最大 16M LongBlob 最大 4G
超长字符串或者二进制数据分别可以用TEXT(65535),BLOB(64k)保存,但是尝试使用二进制保存失败,便使用TEXT保存,但是一张500多kb的图片经过base64加密的字符长度高度75万!,仅仅靠一个TEXT是存不下去的,而且应该也会造成严重的性能问题,所以分割成N份保存,这里以50000字符长度为一个单位.记录cid,方便拼接
数据表photo,用于保存图片数据,结构如下:
CREATE TABLE `photo` ( `id` int(10) unsigned NOT NULL auto_increment, `typeid` int(10) unsigned NOT NULL, `cid` int(10) unsigned NOT NULL, `type` varchar(100) NOT NULL, `binarydata` mediumblob NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
1、大家可以先把图片进行压缩,不失真就好,网上 https://tinypng.com/developers 这个可以看一下;
2、准备一个前端,然后用来上传图片,中间可能大的图片上传不上去,获取为空,需要修改下php.ini的限制;
3、上传之后,就是需要对图片进行处理,这里说的处理也是获取图片的二进制,然后进行加密,分割,分块存储,当然上表中的typeid只是用来做一个标识,标记的是哪一个图片,这个可以自行处理,作图片归属唯一标识;cid 是用来做图片分割的块存储记录,将会获取图片还需要根据此标识,拼接数据存储;
4、获取就很简单了,根据typeid 标识分组获取一个图片列表;
5、分别取获取该图片源;拼接二进制数据,解密等等。
注意:只为大体上如何实现,具体参数过滤;数据字段可相应更改;然后需要考虑的是后续的上传完成后,怎么去对图片进行验证,怎么才知道可以上传成功(这个可以 可以参考调用获取图片)等;
首先,是前端代码:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <form action="form.php" method="post" enctype="multipart/form-data"> <input type="text" name="username" value=""> <!--这个字段没什么用--> <input type="file" name="file" value=''> <input type="hidden" name="act" value="add" /> <!--因为后端程序在一个文件处理,所以此字段用来标识进行后端哪个处理--> <input type="submit" name="b1" value="提交" /> </form> </body> </html>
后端处理:新建一个form.php文件
// 连接数据库 $conn = @mysql_connect('localhost','root','') or die('Connect Error:'.mysql_connect_errno().":".mysql_connect_error()); mysql_select_db('test',$conn); mysql_set_charset('utf8'); $action = isset($_REQUEST['act'])? $_REQUEST['act'] : ''; if($action=='show'){ //显示图片 $id = isset($_GET['typeid'])? intval($_GET['typeid']) : 0; $sqlstr = "select * from photo2 where typeid= $id order by cid asc"; $query = mysql_query($sqlstr) or die(mysql_error()); $imgStr = ''; $type = ''; while($thread=mysql_fetch_assoc($query)){ $imgStr .= $thread['binarydata']; $type = $thread['type']; } $binaryStr = base64_decode($imgStr); header('content-type:'.$type); echo $binaryStr; exit(); } elseif ($action == 'add') //进行图片上传 { $str = file_get_contents($_FILES['file']['tmp_name']); $type = $_FILES['file']['type']; $base64_str = base64_encode($str); $len = strlen($base64_str); $step = ceil($len/50000); var_dump($step); var_dump($base64_str); for ($i=0; $i <$step ; $i++) { $substr = substr($base64_str, $i*50000,50000); $sql = "INSERT INTO photo2(cid,type,binarydata,typeid) values('".$i."','".$type."','".$substr."',3)"; $res = mysql_query($sql); } } else //默认显示列表 { $sqlstr = "select * from photo2 group by typeid order by typeid desc"; $query = mysql_query($sqlstr) or die(mysql_error()); while($thread=mysql_fetch_assoc($query)){ $result[]= $thread; } foreach($result as $val){ echo '<p><img src="form2.php?act=show&typeid='.$val['typeid'].'&t='.time().'" width="150"></p>'; } }
1、图片还是压缩一下在进行处理比较好,这样会占用更少空间
2、访问 http://localhost/form.html 上传图片,
3、对图片进行唯一标识的储存,修改 typeid,上传完成后,既可以通过访问 :http://localhost/form.php?act=show&typeid=3 可以在浏览器该图片是否正常上传 来进行测试!
4、上传原图、压缩图之后,可以进行图片列表的显示, 访问:http://localhost/form.php ,即可显示上传的2张压缩图和一张原图!
参考:
本文为崔凯原创文章,转载无需和我联系,但请注明来自冷暖自知一抹茶ckhttp://www.cksite.cn