如何通过Shell脚本插入图片Blob至数据库并使用PHP显示?
解决Shell脚本插入图片Blob到数据库及PHP显示的问题
我完全懂你折腾两天没进展的憋屈感,咱们直接来填坑——先把Shell脚本的问题搞定,再给你写PHP显示图片的代码。
第一步:修复Shell脚本的问题
你的脚本里有几个语法和权限的坑,我给你调整好了,顺便加了注释方便理解:
修复后的Shell脚本
#!/bin/bash # 注意:Bash变量赋值不能有空格!这是你原来脚本的核心问题之一 DB_USER="root" DB_PASS="" DB_NAME="raven" TABLE="gambar" # 停止motion服务 killall motion sleep 1 # 生成带时间戳的文件名和完整路径 TANGGAL=$(date +"%Y-%m-%d_%H-%M-%S") IMAGE_PATH="/var/www/html/$TANGGAL.jpg" # 拍摄图片 raspistill -t 2000 -w 1280 -h 720 -q 100 -o "$IMAGE_PATH" sleep 1 # 关键:调整文件权限,让MySQL用户能读取这个图片 chmod 644 "$IMAGE_PATH" # 插入到数据库(注意字符串字段要加单引号,避免SQL语法错误) mysql --user="$DB_USER" --password="$DB_PASS" "$DB_NAME" << EOF # 明确指定字段名,避免表结构变动时出错 INSERT INTO $TABLE (tanggal, gambar_blob) VALUES ('$TANGGAL', LOAD_FILE('$IMAGE_PATH')); EOF # 可选:如果不需要保留本地图片,执行这行删除 # rm "$IMAGE_PATH"
脚本修复要点说明
- 变量赋值无空格:Bash里
DB_USER = "root"这种写法是错的,必须改成DB_USER="root",所有变量都要统一这个格式。 - 字符串加引号:
$TANGGAL是日期字符串,插入SQL时必须用单引号括起来,否则MySQL会把它当成字段名报错。 - 文件权限处理:MySQL的
LOAD_FILE函数需要读取文件的权限,所以用chmod 644确保mysql用户能访问图片。 - 字段名明确化:原来的
INSERT INTO $TABLE VALUES (NULL,$TANGGAL,...)容易因为表字段顺序变动出错,明确写字段名更稳妥。
额外注意:MySQL的secure_file_priv限制
如果执行脚本后图片没插入成功,大概率是这个参数的问题:
- 执行
mysql -u root -e "SHOW VARIABLES LIKE 'secure_file_priv'"查看设置 - 如果输出值是某个目录,那你的图片必须放在这个目录下;如果是
NULL,说明禁止了LOAD_FILE,需要修改my.cnf(或my.ini):
改完重启MySQL服务即可。secure_file_priv = "/var/www/html/"
第二步:PHP显示数据库中的Blob图片
接下来写一个PHP文件,用来从数据库读取Blob并输出为图片:
创建show_image.php文件
<?php // 数据库连接信息,和Shell脚本保持一致 $dbHost = 'localhost'; $dbUser = 'root'; $dbPass = ''; $dbName = 'raven'; // 建立数据库连接 $conn = new mysqli($dbHost, $dbUser, $dbPass, $dbName); if ($conn->connect_error) { die("数据库连接失败: " . $conn->connect_error); } // 通过GET参数获取图片ID(比如访问:http://你的服务器IP/show_image.php?id=1) $imageId = $_GET['id'] ?? null; if (!$imageId) { die("请指定图片ID,例如:show_image.php?id=1"); } // 使用预处理语句查询,避免SQL注入风险 $sql = "SELECT gambar_blob FROM gambar WHERE id = ?"; $stmt = $conn->prepare($sql); $stmt->bind_param("i", $imageId); $stmt->execute(); $stmt->store_result(); $stmt->bind_result($imageBlob); $stmt->fetch(); // 检查是否找到图片 if (!$imageBlob) { die("未找到对应ID的图片"); } // 设置响应头为JPG格式,输出图片内容 header("Content-Type: image/jpeg"); echo $imageBlob; // 清理资源 $stmt->close(); $conn->close(); ?>
使用说明
- 把这个文件放到
/var/www/html/目录下 - 访问
http://你的服务器IP/show_image.php?id=X(X是数据库里图片的id值),就能直接看到图片了 - 如果想通过日期查询图片,可以修改SQL语句为:
然后访问$tanggal = $_GET['date'] ?? null; $sql = "SELECT gambar_blob FROM gambar WHERE tanggal = ?"; $stmt->bind_param("s", $tanggal);show_image.php?date=2024-05-20_15-30-00即可。
最后检查数据库表结构
确保你的gambar表字段类型正确:
id:INT类型,设置为自增主键tanggal:VARCHAR(50)类型,用来存时间戳字符串gambar_blob:MEDIUMBLOB类型(BLOB最大只能存64KB,720P的JPG肯定超过这个大小,MEDIUMBLOB能存16MB,足够用)
内容的提问来源于stack exchange,提问作者Muhammad Tirta
相关产品推荐
相关产品推荐

