在CodeIgnitor框架下上传图片至MySQL的BLOB字段并展示的实现方法
没问题,虽然把图片存在数据库BLOB里确实不是最佳实践(毕竟会增大数据库体积、拖慢查询速度),但既然业务需求必须这么做,我给你整理一套完整的CodeIgniter实现步骤,都是实际跑通的代码:
1. 先创建数据库表
首先得建个存图片的表,除了BLOB字段,还要保留图片类型、文件名这些辅助信息,方便后续展示:
CREATE TABLE `images` ( `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, `image_name` varchar(255) NOT NULL, `image_type` varchar(100) NOT NULL, `image_data` longblob NOT NULL, `created_at` datetime DEFAULT CURRENT_TIMESTAMP );
这里用longblob是因为普通blob容量有限,大一点的图片会存不下。
2. 编写Model(处理数据库操作)
在application/models下创建Image_model.php,专门负责图片的插入和查询:
<?php class Image_model extends CI_Model { public function __construct() { parent::__construct(); $this->load->database(); } // 把图片数据插入数据库 public function insert_image($data) { return $this->db->insert('images', $data); } // 根据ID获取单张图片的信息 public function get_image($id) { $query = $this->db->get_where('images', array('id' => $id)); return $query->row(); } } ?>
3. 编写Controller(处理上传和展示逻辑)
在application/controllers下创建Image_upload.php,负责处理表单提交、上传验证、调用模型,还有专门输出图片的方法:
<?php class Image_upload extends CI_Controller { public function __construct() { parent::__construct(); $this->load->model('Image_model'); $this->load->library('upload'); $this->load->helper('url', 'form'); } // 展示上传表单和已上传的图片列表 public function index() { $data['images'] = $this->db->get('images')->result(); $this->load->view('image_upload_view', $data); } // 处理图片上传的核心逻辑 public function upload() { // 配置上传参数 $config['upload_path'] = './uploads/temp/'; // 临时存储目录,用完可以删掉 $config['allowed_types'] = 'gif|jpg|jpeg|png'; $config['max_size'] = 2048; // 限制2MB,按需调整 $config['encrypt_name'] = TRUE; // 避免文件名冲突 $this->upload->initialize($config); if (!$this->upload->do_upload('userfile')) { // 上传失败,返回错误提示 $error = array('error' => $this->upload->display_errors()); $this->load->view('image_upload_view', $error); } else { // 上传成功,读取文件内容 $upload_data = $this->upload->data(); $image_file = fopen($upload_data['full_path'], 'r'); $image_data = fread($image_file, filesize($upload_data['full_path'])); $image_data = mysqli_real_escape_string($this->db->conn_id, $image_data); // 转义特殊字符,避免数据库报错 fclose($image_file); // 准备插入数据库的数据 $data = array( 'image_name' => $upload_data['file_name'], 'image_type' => $upload_data['file_type'], 'image_data' => $image_data ); // 插入数据库 $this->Image_model->insert_image($data); // 删除临时文件(可选,不需要物理文件的话就删掉) unlink($upload_data['full_path']); // 重定向回上传页面 redirect('image_upload/index'); } } // 专门用来输出图片的方法,供img标签调用 public function show_image($id) { $image = $this->Image_model->get_image($id); if ($image) { header("Content-type: " . $image->image_type); echo $image->image_data; exit(); } else { // 找不到图片时返回默认图(自己准备一张default.png放在uploads目录) header("Content-type: image/png"); readfile('./uploads/default.png'); exit(); } } } ?>
⚠️ 注意:要先创建./uploads/temp/目录,并且给它设置写权限(比如chmod 777 ./uploads/temp/),不然上传会失败。
4. 编写View(上传表单和展示页面)
在application/views下创建image_upload_view.php:
<!DOCTYPE html> <html> <head> <title>图片上传到BLOB</title> </head> <body> <h2>上传图片</h2> <?php if (isset($error)) { echo '<p style="color:red;">'.$error.'</p>'; } ?> <?php echo form_open_multipart('image_upload/upload'); ?> <input type="file" name="userfile" size="20" /> <br /><br /> <input type="submit" value="上传图片" /> </form> <h2>已上传的图片</h2> <?php if (isset($images) && !empty($images)): ?> <?php foreach ($images as $img): ?> <div style="margin:10px;display:inline-block;"> <p><?php echo $img->image_name; ?></p> <img src="<?php echo site_url('image_upload/show_image/'.$img->id); ?>" alt="<?php echo $img->image_name; ?>" width="200" /> </div> <?php endforeach; ?> <?php else: ?> <p>还没有上传任何图片</p> <?php endif; ?> </body> </html>
一些关键注意事项
- 数据库性能:BLOB会让表体积快速膨胀,查询速度变慢,如果图片数量多,建议定期归档或者在业务允许时切换到文件存储方案。
- 上传大小限制:除了CodeIgniter里的
max_size,还要修改php.ini里的upload_max_filesize和post_max_size,不然大图片会上传失败。 - 安全问题:插入BLOB时一定要转义特殊字符,代码里用的
mysqli_real_escape_string能有效避免注入和数据库报错。
内容的提问来源于stack exchange,提问作者hanshika




