PHP连接SQL Server成功 读取数据报null值数组偏移访问错误
问题现象
SQL Server数据库连接正常,但读取查询结果字段时抛出错误:Trying to access array offset on value of type null
业务代码
PHP数据读取逻辑
//Read RMS DB if( $conCore2 === false ) { echo "Could not connect to Core2 Server.\n"; die( print_r( sqlsrv_errors(), true)); }else{ if(isset($_GET['id'])) { try { // 根据docno获取文档状态和文件存储路径 $sql = "SELECT [status] ,[FileLocation] FROM [dbo].[tbl_Documents] where DocNo='".$_GET['id']."'"; $resultset = sqlsrv_query($conCore2, $sql); if($resultset === false) { die( print_r( sqlsrv_errors(), true) ); } $row = sqlsrv_fetch_array($resultset, SQLSRV_FETCH_ASSOC); echo "inside"; if (isset($row['FileLocation'])){ echo $row['FileLocation']; } echo $row['FileLocation']; echo $row['status'];
前端展示页面代码
<div class="wrapper-container-fluid container-fluid pb-5"> <div class="wrapper-container container p-5 bg-white rounded"> <div class="row"> <div class="col"> <h1 class="header">Search</h1> <?php echo $_GET['id']; echo $status; ?> <input type="hidden" name="id" value="<?php echo isset($_GET['id']) ? $_GET['id'] :'' ?>"> </div> </div> </div> </div>
已完成排查项
- 输出
$_GET['id']传递的文档编号,值可正常显示 - 用
isset校验$row['FileLocation'],确认该变量无有效值 - 打印拼接后的SQL语句,语法无错误

- 核查数据库表数据,确认DocNo为
202205-00011的记录存在,且status、FileLocation字段值非空
问题定位与修复
报错直接原因是sqlsrv_fetch_array返回了null——也就是本次查询没有命中任何行,后续直接用$row['字段名']的方式访问数组下标,本质是在null值上取数组偏移,就会触发这个错误。
之前的排查只验证了SQL语法正确、数据库内存在对应记录,漏掉了几个最容易导致查询匹配失败的场景:
- 传入的
$_GET['id']前后带有不可见字符(空格、换行、全角空格、零宽字符),肉眼看值正确,但实际和数据库存储的值不匹配 - 数据库连接指向了错误环境(比如连到测试库而非存有目标数据的生产库),对应库中没有这条记录
- 字符串拼接SQL存在字符编码/转义问题,比如DocNo字段使用特殊排序规则,特殊字符编码不匹配导致条件失效
- 现有代码逻辑有漏洞:在
isset($row['FileLocation'])判断之外,还写了一行无条件执行的echo $row['FileLocation'];,哪怕查询命中行,这行也会重复输出内容,属于冗余错误代码
按以下步骤修复即可:
- 读取查询结果后先做非空判断,不要直接访问数组下标:
$row = sqlsrv_fetch_array($resultset, SQLSRV_FETCH_ASSOC); if ($row === null) { die("查询无匹配记录,当前传入的DocNo为:" . var_export(trim($_GET['id']), true)); }
- 替换字符串拼接SQL的写法,改用参数化查询,同时对传入参数做trim处理清除前后空白,从根源避免SQL注入、转义错误、编码不匹配问题:
$sql = "SELECT [status], [FileLocation] FROM [dbo].[tbl_Documents] WHERE DocNo = ?"; $params = [trim($_GET['id'])]; $resultset = sqlsrv_query($conCore2, $sql, $params);
- 如果仍然返回空行,执行SQL查询当前连接的数据库名,确认是否连错库:
$checkDb = sqlsrv_query($conCore2, "SELECT DB_NAME() AS currentDb"); $dbRow = sqlsrv_fetch_array($checkDb, SQLSRV_FETCH_ASSOC); var_dump($dbRow['currentDb']); // 核对输出的库名是否和你存数据的库一致
- 删除
if (isset($row['FileLocation']))判断外多余的那行echo $row['FileLocation'];,避免重复输出。
内容的提问来源于stack exchange,提问作者Kym NT
相关产品推荐
相关产品推荐

