为什么请求服务端数据库超过100行数据时返回结果为空?
问题根因定位
你的问题本质是大小数据量下响应有效性差异导致,并非无法拉取大体积内容,核心问题点分布在服务端和客户端两侧:
服务端PHP现存问题
- 存在多处多余输出破坏JSON结构:
- 非意大利语分支的调试输出
echo ("IL VALORE DI language non è it.....".$language);会直接写入响应 - 参数错误分支重复输出
echo json_encode($responce);,和末尾的统一输出拼接后形成无效JSON
- 非意大利语分支的调试输出
- 响应头位置错误:
header('Content-type:application/json');放在了逻辑处理之后,如果前面有任何输出(包括PHP报错、警告)都会导致头信息发送失败,返回内容类型异常被客户端拦截 - 未初始化变量:
$result_array仅在查询有结果时赋值,无结果时调用array_push会触发PHP Notice警告,开了display_errors=1的情况下警告内容会混入响应破坏JSON结构 - 大序列JSON生成时可能触发PHP内存限制、执行超时,导致响应截断
客户端Android现存问题
- POST请求开启了缓存:
conn.setUseCaches(true),POST属于非幂等请求,缓存机制可能拦截超过大小阈值的响应 - 未设置超时时间:大数据量传输时读取时间更长,无超时配置会导致连接提前中断
- 未校验HTTP状态码:服务端如果返回500/400等错误码时,直接读输入流会返回空内容
修复方案
服务端PHP修复
<?php // 头信息放最开头,所有输出之前 header('Content-type:application/json'); ini_set('display_errors', 0); // 生产环境关闭错误输出,避免污染响应 ini_set('display_startup_errors', 0); error_reporting(E_ALL | E_STRICT); ini_set('memory_limit', '128M'); // 提升内存限制 ini_set('max_execution_time', 30); // 延长执行超时到30秒 $host ='localhost'; $username ='***'; $pwd ='**'; $db ='MYDB'; $responce =array(); $responce["success"]= 0 ; $responce["message"]= "Error at start"; $result_array = []; // 提前初始化结果数组 $json=file_get_contents('php://input'); $obj_json=json_decode($json,TRUE); if(isset($obj_json)){ $language=$obj_json['Language']; $connect = mysqli_connect($host,$username,$pwd,$db) or die('Unabletp connect'); if(mysqli_connect_error($connect)){ $responce['success']=0; $responce['message']="NO CONNECTION NEW_SPECIFIC_PRODUCT"; }else{ if(strcasecmp($language,"it")== 0){ $sql_find = "SELECT FAMILY_PRODUCT,CATEGORY_PRODUCT,SPECIFIC_PRODUCT,NAME_SPECIFIC FROM NEW_SPECIFIC_PRODUCT_IT;"; $result= mysqli_query($connect,$sql_find) or die ("Error: ". mysqli_error($connect)." with query "); if(mysqli_num_rows($result)> 0){ $responce["success"]= 1 ; $i=0; while ($row = mysqli_fetch_array($result)){ $result_array[$i]= array( "FAMILY_PRODUCT" => $row["FAMILY_PRODUCT"], "CATEGORY_PRODUCT" =>$row["CATEGORY_PRODUCT"], "SPECIFIC_PRODUCT" => $row["SPECIFIC_PRODUCT"], "NAME_SPECIFIC" => $row["NAME_SPECIFIC"] ); $i++; } $responce['message']="I VALORI SONO STATI TROVATI"; }else{ $responce['success']=0; $responce['message']="NO DATA IN NEW_SPECIFIC_PRODUCT_IT"; } }else{ // 删掉调试echo语句 $sql_find = "SELECT * FROM NEW_SPECIFIC_PRODUCT_EN;"; $result= mysqli_query($connect,$sql_find) or die ("Error: ". mysqli_error($connect)." with query "); if(mysqli_num_rows($result)> 0){ $responce["success"]= 1 ; $i=0; while ($row = mysqli_fetch_array($result)){ $result_array[$i]= array( "FAMILY_PRODUCT" =>$row["FAMILY_PRODUCT"], "CATEGORY_PRODUCT"=>$row["CATEGORY_PRODUCT"], "SPECIFIC_PRODUCT"=>$row["SPECIFIC_PRODUCT"], "NAME_SPECIFIC"=>$row["NAME_SPECIFIC"] ); $i++; } }else{ $responce['success']=0; $responce['message']="NO DATA IN NEW_SPECIFIC_PRODUCT_EN"; } } mysqli_close($connect); array_push($responce,$result_array); } }else{ $responce['success']=0; $responce['message']="Parameters are not correct"; // 删掉重复输出语句 } // 加参数避免中文转义 echo json_encode($responce, JSON_UNESCAPED_UNICODE); ?>
客户端Android修复
private String makeHttpRequestJsonListSpecific(String languageTOpass, String urlAdress) { String json = ""; try { JSONObject Language_Json = new JSONObject(); Language_Json.put("Language",languageTOpass); String Message_send = Language_Json.toString(); URL url = new URL(urlAdress); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setDoOutput(true); conn.setDoInput(true); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); conn.setRequestProperty("Accept", "application/json"); conn.setUseCaches(false); // 关闭POST请求缓存 conn.setConnectTimeout(15000); // 连接超时15秒 conn.setReadTimeout(30000); // 读取超时30秒 conn.connect(); OutputStreamWriter request = new OutputStreamWriter(conn.getOutputStream()); request.write(Message_send); request.flush(); request.close(); // 先校验状态码 int statusCode = conn.getResponseCode(); InputStream inputStream; if (statusCode == 200) { inputStream = conn.getInputStream(); } else { inputStream = conn.getErrorStream(); // 这里可以打印错误流内容排查服务端错误 } BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); StringBuilder result = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { result.append(line).append("\n"); } json = result.toString(); Log.d(TAG, "响应大小:" + json.getBytes().length); conn.disconnect(); } catch (IOException | JSONException e ) { Log.e(TAG, "请求错误:" + e.getMessage(), e); } return json; }
大数据量拉取优化方案
如果后续数据量持续增长,可以采用以下方案提升稳定性:
- 分页拉取:接口新增
page、page_size参数,每次拉100条分批次拉取,失败后仅重传失败分页,无需全量重试 - 压缩传输:服务端开启gzip压缩,JSON体积可降低70%以上,客户端添加请求头
Accept-Encoding: gzip,收到响应后用GZIPInputStream解压即可 - 静态全量包:如果数据更新频率低,可定时将整表导出为静态JSON文件,首次启动直接下载静态文件,比动态接口性能高5倍以上,不会触发PHP执行超时
内容的提问来源于stack exchange,提问作者Andrea
相关产品推荐
相关产品推荐

