Android应用MySQL转JSON接口报错:非法字符串偏移问题排查
看起来你遇到的两个问题都是因为对PDO的fetch方法返回值理解有误,以及函数职责划分不清导致的,我来帮你一步步解决:
问题原因分析
非法字符串偏移警告:
你用$stmt->fetch(PDO::FETCH_ASSOC)获取的是单条用户记录的关联数组(比如['username'=>'张三', 'fullname'=>'张三', 'address'=>'xxx']),而不是多条记录组成的数组集合。当你用foreach($userRows as $rows)遍历这个单条记录数组时,$rows会依次取到每个字段的值(比如第一个循环$rows是'张三',是字符串类型),这时候再尝试$rows['username']就相当于对字符串使用数组索引,自然会抛出“非法字符串偏移”的警告。接口返回失败:
你修改后的fetchUserData函数直接在内部echo json_encode($response)输出JSON,但调用它的fetch_api.php还会再次执行echo json_encode($arr),这会导致最终输出的内容是两段JSON拼接在一起,格式完全错误,接口自然返回失败。
修正后的代码实现
第一步:修正lib.php的fetchUserData函数
让这个函数只负责从数据库获取数据,不处理响应输出,保持职责单一:
public function fetchUserData($username) { try { $stmt = $this->db->prepare("SELECT * FROM user_profile WHERE username=:username"); $stmt->execute(array(':username' => $username)); // 获取单条匹配的用户记录 $userRow = $stmt->fetch(PDO::FETCH_ASSOC); if($userRow) { // 找到用户,返回用户数据数组 return $userRow; } else { // 未找到用户,返回false return false; } } catch(PDOException $ex) { // 建议将错误记录到日志,而不是直接输出给前端 error_log($ex->getMessage()); return false; } }
第二步:修正fetch_api.php的响应逻辑
在这个文件里统一处理响应格式,避免重复输出:
<?php require_once '../database/database.php'; if($_SERVER['REQUEST_METHOD'] == 'POST') { // 先检查username参数是否存在,避免未定义索引警告 $username = $_POST['username'] ?? ''; $response = array(); if(empty($username)) { $response['success'] = 0; $response['message'] = "Username parameter is required"; echo json_encode($response); exit; } $userData = $user->fetchUserData($username); if($userData) { $response['success'] = 1; $response['message'] = "Success fetching user data"; // 组装需要返回的用户字段 $response['user'] = array( 'username' => $userData['username'], 'fullname' => $userData['fullname'], 'address' => $userData['address'] // 可以继续添加其他需要返回的字段,比如email、phone等 ); echo json_encode($response); } else { $response['success'] = 0; $response['message'] = "No user found with this username"; echo json_encode($response); } } ?>
额外说明
如果你的需求是获取多条用户记录(比如查询所有用户),那才需要用$stmt->fetchAll(PDO::FETCH_ASSOC)获取数组集合,然后用foreach遍历。但根据你的场景,是根据唯一的username查询单用户,所以直接用fetch就足够了。
内容的提问来源于stack exchange,提问作者user14547421

