3.9 利用数据库保存图片
很多朋友有在自己的博客(blog)上贴照片的经验吧。很多免费软件,如MSN等也提供了上传自己的照片,并管理相册的功能。
有没有想过做一个自己相册呢?本节将帮助你实现做成自己的相册的愿望,如图所示。相册将会以自己命名的类别进行管理,通过在URL的最后指定类别名称来调出相应的相册。例如要调出名为旅游“travel”的相册时,必须在URL的最后加上“/travel”。
本例要点
本节将上传的图片保存在数据库中的方式,实现相册管理。图片文件将在数据库中以二进制代码的形式保存。“二进制代码的形式”听起来好像挺神秘、挺难的,其实在PHP中利用PDO类能很简单地实现图片在数据库中的存储与取出。
相反,需要好好理解的是,为什么要将图片保存在数据库中?在数据库中保存图片有些什么好处,又有什么坏处?图片除了保存在数据库中外,也可以保存在服务器的目录中。当图片保存在数据库中时,可以很方便地进行图片的权限控制(用户访问权限等)。但是,当图片文件很大时,容易参加数据库的负担,影响数据库的性能。因此,务必根据实际需要,选择适当的图片保存方式。
目录结构
数据库的表结构数据库的表结构如表3-15所示。
表3-15 相册(photo)
本例代码
此处取出扩展路径(参照本节后的补充资料)部分的值,$_SERVER['REQUEST_URI']为当前页面的URI(如“/samples/chap3/photo/photo.php/travel”),basename函数抽出URI的末尾部分并将其保存在变量$category(相册分类)。
以相册分类$category为条件检索表photo。
根据抽出的结果集显示图片预览。为了使图片以每行3个的形式显示,请注意在26,43行进行了换行控制。26行,当前序号除以3余1(即1,4,7…)时,输出一行开始的<tr>;43行,当前序号除以3余0(即3,6,9…)时,输出一行结束的“</tr>”。
由showImage.php脚本从数据库中取出图片。URL的末尾是取得图片的条件。
以查询信息pid为条件,检索表photo取得图片数据。
bindColumn方法以指定的数据类型取得抽出的列的值,并保存在指定的变量中。第9行以字符串的形式取得第一列(content_type)的值,并将值保存在变量$type。同样,第10行以二进制数据的形式取得第二列(data)的值,并将值保存在变量$data。
当数据取得模式为PDO::FETCH_BOUND,抽出值将自动放上面bindColumn方法中设定的变量中。另一方面,如果使用了bindColumn方法,那么必须得将数据取得模式设为PDO::FETCH_BOUND。
图片信息输出。
向数据库里登录表单里输入的图片。上传数据的处理方法请参照2.3节。
请注意第10行,bindValue方法的第三个参数设定上传文件的保存类型(PDO::PARAM_LOB为二进制数据类型)。bindValue方法的第三个参数可以省略,默认为字符串类型。
处理结束,跳转到相册画面(photo.php)。
从表photo中删除指定图片ID的图片。
处理结束,跳转到相册画面(photo.php)。
补充
扩展路径
扩展路径(或曰追加路径)就是URL的最后以附加输入参数形式显示的信息,针对本节的例子来说,就是指“/travel”部分。与查询信息以“?键=值”形式的附加在URL路径后面类似,扩张路径也作为URL路径的一部分附加在URL的最后。
根据搜索引擎的不同,有些搜索引擎在索引时,会忽略URL后的查询(Query)信息。而如果以扩展路径的形式传递信息时,就不存在被忽略的担心。从SEO(Search Engine Optimization,搜索引擎优化)的角度来看,使用扩展路径的形式传递参数比查询信息方式有利。