PHP读取SQL Server image字段显示图片及WooCommerce导入问题
解决SQL Server二进制图片读取问题并导入WooCommerce
一、修复PHP读取SQL Server二进制图片的问题
问题原因
var_dump显示MainImage为string(0),是因为PHP连接SQL Server时,默认配置未正确处理大二进制字段(image类型),导致数据读取不全或为空。
解决方案(分两种扩展实现)
1. 使用sqlsrv扩展
- 首先调整连接配置,增大缓冲区以支持大文件:
$serverName = "你的SQL Server地址"; $connectionInfo = [ "Database" => "数据库名", "UID" => "用户名", "PWD" => "密码", "ClientBufferMaxKBSize" => 1024 * 1024 * 20 // 20MB,根据实际图片大小调整 ]; $conn = sqlsrv_connect($serverName, $connectionInfo);
- 读取数据时,用
sqlsrv_get_field指定二进制流类型获取:
$query = "SELECT p.ProductID, p.Name, mi.MainImage FROM tbl p JOIN tblImg mi ON p.ProductID = mi.ProductID WHERE p.ProductID = ?"; $params = [123]; // 替换为实际产品ID $stmt = sqlsrv_query($conn, $query, $params); if ($stmt && sqlsrv_fetch($stmt)) { $productId = sqlsrv_get_field($stmt, 0); $productName = sqlsrv_get_field($stmt, 1); // 获取二进制图片流并转为字符串 $imageStream = sqlsrv_get_field($stmt, 2, SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY)); $imageData = stream_get_contents($imageStream); }
2. 使用PDO_SQLSRV扩展
- 连接时关闭字符串化获取,确保二进制数据不被转换:
$dsn = "sqlsrv:Server=你的SQL Server地址;Database=数据库名"; $pdo = new PDO($dsn, "用户名", "密码"); $pdo->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false); $stmt = $pdo->prepare("SELECT p.ProductID, p.Name, mi.MainImage FROM tbl p JOIN tblImg mi ON p.ProductID = mi.ProductID WHERE p.ProductID = ?"); $stmt->execute([123]); $row = $stmt->fetch(PDO::FETCH_ASSOC); $imageData = $row['MainImage']; // 直接获取二进制数据
验证图片读取是否正常
输出图片测试:
// 自动判断图片类型 function getImageMimeType($data) { $signature = substr($data, 0, 4); if ($signature === "\x89PNG") return 'image/png'; if (substr($signature, 0, 2) === "\xFF\xD8") return 'image/jpeg'; if ($signature === "GIF8") return 'image/gif'; return 'image/jpeg'; } header("Content-Type: " . getImageMimeType($imageData)); echo $imageData;
如果能正常显示图片,说明读取成功。
二、将图片导入WooCommerce(新产品/现有产品)
前置条件
代码需在WordPress环境下运行(WooCommerce依赖WP核心函数)。
步骤1:将二进制图片上传到WP媒体库
// 自动判断图片扩展名 function getImageExtension($data) { $signature = substr($data, 0, 4); if ($signature === "\x89PNG") return 'png'; if (substr($signature, 0, 2) === "\xFF\xD8") return 'jpg'; if ($signature === "GIF8") return 'gif'; return 'jpg'; } $extension = getImageExtension($imageData); $tempFile = tempnam(sys_get_temp_dir(), 'wc_img_') . '.' . $extension; file_put_contents($tempFile, $imageData); // 上传到媒体库 $upload = wp_upload_bits(basename($tempFile), null, file_get_contents($tempFile)); $attachId = null; if (!$upload['error']) { $attachment = [ 'post_mime_type' => $upload['type'], 'post_title' => sanitize_file_name($productName), 'post_status' => 'inherit' ]; $attachId = wp_insert_attachment($attachment, $upload['file']); // 生成图片元数据 require_once(ABSPATH . 'wp-admin/includes/image.php'); $attachMeta = wp_generate_attachment_metadata($attachId, $upload['file']); wp_update_attachment_metadata($attachId, $attachMeta); } // 删除临时文件 unlink($tempFile);
步骤2:导入新产品到WooCommerce
if ($attachId) { $product = new WC_Product_Simple(); $product->set_name($productName); $product->set_regular_price(19.99); // 替换为实际产品价格 $product->set_image_id($attachId); // 设置主图 // 可添加其他产品属性:库存、分类等 $product->save(); }
步骤3:更新现有产品的图片
$existingProductId = 456; // 替换为实际现有产品ID $product = wc_get_product($existingProductId); if ($product && $attachId) { $product->set_image_id($attachId); // 如需添加画廊图片,使用:$product->set_gallery_image_ids([$attachId1, $attachId2]) $product->save(); }
内容的提问来源于stack exchange,提问作者Gas Test
相关产品推荐
相关产品推荐

