PHP使用while循环遍历SQL结果保存图片时报bool数组偏移错误如何解决
报错根因
你遇到的报错核心原因是sqlsrv_fetch()函数的返回值不符合预期:该函数仅会在读取成功时返回true,读取失败/无数据时返回false,不会返回当前行的数组数据,所以你尝试用$row['ProductCode']访问布尔值的数组下标自然会触发报错。
解决方案
方案一:改用sqlsrv_fetch_array()直接获取行数组(推荐)
这个函数会直接返回当前行的关联/索引数组,不需要额外调用sqlsrv_get_field读取普通字段,代码更易读:
$sql = "SELECT Picture ,ParentId ,P.Code as 'ProductCode' FROM dbo.IWS_Stock_Images img LEFT OUTER JOIN ic.Product P on P.ProductId=img.ParentId WHERE P.Code IN('GAI4030','GAI4037A', 'GAI1008', 'GAI4990')"; $stmt = sqlsrv_query($conn, $sql); if ($stmt === false) { echo "Error (sqlsrv_query): ".print_r(sqlsrv_errors(), true); exit; } $A = 1; // 用SQLSRV_FETCH_ASSOC指定返回关联数组,直接用字段名做下标 while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) { $idd = $row['ProductCode']; // Picture字段是二进制流,单独指定类型读取 $image = sqlsrv_get_field($stmt, 0, SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY)); file_put_contents($idd.'.jpg', $image); $A++; } // 用完释放资源 sqlsrv_free_stmt($stmt);
方案二:保留sqlsrv_fetch()写法,单独读取ProductCode字段
如果你要保留原有的sqlsrv_fetch()逻辑,就需要用sqlsrv_get_field读取第三个字段(索引从0开始,ProductCode是SELECT语句里的第三个字段,所以索引为2)的值:
// 其他代码不变,仅修改循环部分即可 while (sqlsrv_fetch($stmt)) { $idd = sqlsrv_get_field($stmt, 2); $image = sqlsrv_get_field($stmt, 0, SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY)); file_put_contents($idd.'.jpg', $image); $A++; }
注意事项
- 你的SQL用了
LEFT JOIN但WHERE条件里筛选了P.Code,实际效果等同于INNER JOIN,如果存在没有对应产品的图片数据会被过滤,如果你需要保留无对应产品的图片,可以把筛选条件移到LEFT JOIN的ON子句里。 - 写入文件前可以先判断
$idd是否为空,避免出现空文件名的异常。
内容的提问来源于stack exchange,提问作者Mohan Wijesena
相关产品推荐
相关产品推荐

