You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

安卓端PHP上传图片至Oracle数据库(Blob格式)遇问题求助

嘿,我看你Web端的图片上传到Oracle BLOB的逻辑没问题,但安卓端踩了个常见的坑——你当前的PHP代码是基于Web端文件上传的逻辑写的,和安卓端的上传方式不匹配,我给你拆解问题并给出适配方案:

核心问题分析

你代码里直接把$_POST['image']当作本地文件路径来调用finfo_file()file_get_contents()这些函数,但安卓端上传图片通常有两种方式:要么传Base64编码的字符串,要么以Multipart流上传(和Web端一致),这两种方式下$_POST['image']都不是本地文件路径,自然会报错。


方案1:适配安卓端Base64字符串上传

如果你的安卓代码是把图片转成Base64字符串后通过POST发送,修改PHP代码如下:

<?php 
error_reporting(E_ALL);
ini_set('display_errors', 1);

$conn = oci_connect("test_dev","test_dev","192.168.10.82:1509/testdv"); 
class emp{} 

$image = $_POST['image'] ?? '';
$name = $_POST['name'] ?? '';

// 校验必填参数
if (empty($name) || empty($image)) { 
    $response = new emp(); 
    $response->success = 0; 
    $response->message = "Name or image cannot be empty."; 
    die(json_encode($response)); 
}

// 处理Base64格式:分离MIME类型和二进制数据
$imageParts = explode(";base64,", $image);
if(count($imageParts) !== 2){
    $response = new emp(); 
    $response->success = 0; 
    $response->message = "Invalid image format."; 
    die(json_encode($response));
}

$imageTypePart = explode("image/", $imageParts[0]);
$DIGI_TYPE = "image/" . $imageTypePart[1];
$imageBinary = base64_decode($imageParts[1]);

// 创建临时BLOB并写入数据
$lob = oci_new_descriptor($conn, OCI_D_LOB);
$lob->writeTemporary($imageBinary, OCI_TEMP_BLOB);

// 安全执行SQL:用绑定变量避免注入,不要直接拼接$name!
$sql = "UPDATE LC_BLOCK_LIST_TECH_PERS SET DIGI_SIGN = :DIGI_SIGN , DIGI_TYPE = :DIGI_TYPE WHERE COM_CODE= :COM_CODE"; 
$s = oci_parse($conn, $sql); 
oci_bind_by_name($s, ':DIGI_TYPE', $DIGI_TYPE); 
oci_bind_by_name($s, ':DIGI_SIGN', $lob, -1, OCI_B_BLOB);
oci_bind_by_name($s, ':COM_CODE', $name);

// 执行并处理结果
$executeResult = oci_execute($s, OCI_NO_AUTO_COMMIT);
if($executeResult){
    oci_commit($conn);
    $response = new emp(); 
    $response->success = 1; 
    $response->message = "Image uploaded successfully."; 
    echo json_encode($response);
} else {
    $error = oci_error($s);
    $response = new emp(); 
    $response->success = 0; 
    $response->message = "Database error: " . $error['message']; 
    echo json_encode($response);
    oci_rollback($conn);
}

// 释放资源
$lob->close();
oci_free_statement($s);
oci_close($conn);

关键修改点:

  • 增加了参数合法性校验,包括Base64格式的校验
  • 把Base64字符串解码成二进制数据,再写入BLOB
  • 修复了SQL注入风险:原来直接把$name拼进SQL,改成绑定变量,这是生产环境必须注意的
  • 增加了错误捕获和明确的返回信息,方便安卓端调试

方案2:适配安卓端Multipart/form-data上传(和Web端一致)

如果你的安卓代码是像Web表单那样以文件流上传,那应该用$_FILES来获取上传文件,修改代码如下:

<?php 
error_reporting(E_ALL);
ini_set('display_errors', 1);

$conn = oci_connect("test_dev","test_dev","192.168.10.82:1509/testdv"); 
class emp{} 

$name = $_POST['name'] ?? '';

// 校验文件上传状态
if (empty($name) || !isset($_FILES['image']) || $_FILES['image']['error'] !== UPLOAD_ERR_OK) { 
    $response = new emp(); 
    $response->success = 0; 
    $response->message = "Name is empty or image upload failed."; 
    die(json_encode($response)); 
}

$imageTmpPath = $_FILES['image']['tmp_name'];
$DIGI_TYPE = $_FILES['image']['type'];
$imageBinary = file_get_contents($imageTmpPath);

// 创建临时BLOB并写入数据
$lob = oci_new_descriptor($conn, OCI_D_LOB);
$lob->writeTemporary($imageBinary, OCI_TEMP_BLOB);

// 安全执行SQL
$sql = "UPDATE LC_BLOCK_LIST_TECH_PERS SET DIGI_SIGN = :DIGI_SIGN , DIGI_TYPE = :DIGI_TYPE WHERE COM_CODE= :COM_CODE"; 
$s = oci_parse($conn, $sql); 
oci_bind_by_name($s, ':DIGI_TYPE', $DIGI_TYPE); 
oci_bind_by_name($s, ':DIGI_SIGN', $lob, -1, OCI_B_BLOB);
oci_bind_by_name($s, ':COM_CODE', $name);

// 执行并处理结果
$executeResult = oci_execute($s, OCI_NO_AUTO_COMMIT);
if($executeResult){
    oci_commit($conn);
    $response = new emp(); 
    $response->success = 1; 
    $response->message = "Image uploaded successfully."; 
    echo json_encode($response);
} else {
    $error = oci_error($s);
    $response = new emp(); 
    $response->success = 0; 
    $response->message = "Database error: " . $error['message']; 
    echo json_encode($response);
    oci_rollback($conn);
}

// 释放资源
$lob->close();
oci_free_statement($s);
oci_close($conn);

额外调试技巧

  • 在安卓端上传时,用抓包工具(比如Charles)确认请求参数/文件是否正确发送
  • 开启PHP的错误提示(代码里已经加了),能快速定位后端报错原因
  • 检查Oracle数据库用户的权限,确保有修改目标表和操作BLOB字段的权限

内容的提问来源于stack exchange,提问作者Abdur Rahman

火山引擎 最新活动