Android StringRequest POST传参至PHP脚本返回空JSON问题排查
问题
我编写了一段用于从MySQL数据库查询数据的PHP脚本,查询参数需由Android应用通过POST请求传递,PHP脚本代码如下:
<?php $parametre=$_POST['parametre']; $ordre=$_POST['ordre']; $donneecherchee=$_POST['donneerecherchee']; $auteur=$_POST['auteur']; $recenseur=$_POST['recenseur']; //database constants define('DB_HOST', 'xxx.xxx.xxx.xxx'); define('DB_USER', 'xxxx'); define('DB_PASS', 'xxxxxxxx'); define('DB_NAME', 'xxxxxxx'); // Connect to the MySQL database //connecting to database and getting the connection object $conn = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME); //Checking if any error occured while connecting if (mysqli_connect_errno()) { echo "Failed to connect to MySQL: " . mysqli_connect_error(); die(); } if ($parametre != null && $ordre != null && $auteur != null && $donneecherchee != null) { // echo(" Les paramatres sont:".$parametre.",".$ordre.",".$auteur.",".$donneecherchee.",".$recenseur); if ($auteur == "Mes recensements") { $queryused = "SELECT id, nom, dateprise, cin, observation, recenseur, usedurl FROM tsena WHERE " . $parametre . " = '" . $donneecherchee . "' AND recenseur = '" . $recenseur . "' ORDER BY id " . $ordre.";"; $executedquery = $conn->prepare($queryused); $executedquery->execute(); $executedquery->bind_result($id, $nom, $dateprise, $cin, $observation, $recenseur, $usedurl); $tsena = array(); // traversing through all the result while ($executedquery->fetch()) { $temp = array(); $temp['id'] = $id; $temp['nom'] = $nom; $temp['dateprise'] = $dateprise; $temp['cin'] = $cin; $temp['observation'] = $observation; $temp['recenseur'] = $recenseur; $temp['usedurl'] = $usedurl; array_push($tsena, $temp); } // echo the result as JSON echo json_encode($tsena); } else { $queryused2 = "SELECT * FROM tsena WHERE " . $parametre . " = '" . $donneecherchee . "' ORDER BY id " . $ordre.";"; $executedquery2 = $conn->prepare($queryused2); $executedquery2->execute(); $executedquery2->bind_result($id, $nom, $dateprise, $cin, $observation, $recenseur, $usedurl); $tsena2 = array(); // traversing through all the result while ($executedquery2->fetch()) { $temp = array(); $temp['id'] = $id; $temp['nom'] = $nom; $temp['dateprise'] = $dateprise; $temp['cin'] = $cin; $temp['observation'] = $observation; $temp['recenseur'] = $recenseur; $temp['usedurl'] = $usedurl; array_push($tsena2, $temp); } // echo the result as JSON echo json_encode($tsena2); } }else{ $data = [ "id" => 0, "nom" => "Aucun", "dateprise" => "Aucune date", "cin" => "Aucun CIN", "observation" => "Aucune observation", "recenseur" => "Aucun recenseur", "usedurl" => "Aucune image" ]; // Output the JSON data echo json_encode([$data]); } ?>
我在Android应用中通过POST请求的StringRequest传递参数并获取返回的JSON数据,Android端代码如下:
private void loadProducts(String parametre, String ordre, String donneerecherchee,String auteur,String recenseur) { StringRequest stringRequest = new StringRequest(Request.Method.POST, URL_tsena, new Response.Listener() { @Override public void onResponse(String response) { try { JSONArray array = new JSONArray(response); System.out.println("Reponse du serveur:"+response); //traversing through all the object for (int i = 0; i < array.length(); i++) { JSONObject product = array.getJSONObject(i); //adding the product to product list tsenaList.add(new Tsena( product.getInt("id"), product.getString("nom"), product.getString("cin"), product.getString("dateprise"), product.getString("observation"), product.getString("recenseur") )); } //creating adapter object and setting it to recyclerview TsenaAdapter adapter = new TsenaAdapter(ConsultTsena.this, tsenaList); recyclerView.setAdapter(adapter); } catch (JSONException e) { e.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Toast.makeText(ConsultTsena.this,"Erreur de load:"+error,Toast.LENGTH_LONG).show(); Log.e("Volley Erreur", error.toString()); } }){ @Override protected Map<String, String> getParams() { Map<String, String> params = new HashMap<>(); params.put("parametre", parametre); params.put("ordre", ordre); params.put("donneerecherchee",donneerecherchee); params.put("auteur",auteur); return params; // Set the parameters for the request } }; //adding our stringrequest to queue Volley.newRequestQueue(this).add(stringRequest); }
目前已确认参数已传递、查询语句正确,但Logcat中显示返回空JSON数组[],而在Powershell中执行相同查询能得到结果,请问该如何解决此问题?
解决方法
补充传递
recenseur参数:
当auteur等于"Mes recensements"时,PHP查询会加上recenseur = '$recenseur'的条件,但Android端getParams()方法里没有传递recenseur参数,导致$_POST['recenseur']为空,查询条件变成recenseur = '',自然无法匹配到数据。修改Android代码的getParams(),添加:params.put("recenseur", recenseur);修复SQL注入漏洞并避免参数拼接错误:
当前PHP代码直接拼接参数到SQL语句中,不仅存在严重的SQL注入风险,还可能因为参数包含特殊字符(如单引号)导致查询失效。改用预编译语句的参数绑定方式,同时校验字段名合法性:// 先校验允许查询的字段 $allowedFields = ['nom', 'cin', 'dateprise', 'observation']; // 替换为实际允许的字段 if (!in_array($parametre, $allowedFields)) { echo json_encode([]); die(); } if ($auteur == "Mes recensements") { $queryused = "SELECT id, nom, dateprise, cin, observation, recenseur, usedurl FROM tsena WHERE `$parametre` = ? AND recenseur = ? ORDER BY id ?"; $executedquery = $conn->prepare($queryused); // 绑定参数,s代表字符串类型 $executedquery->bind_param("sss", $donneecherchee, $recenseur, $ordre); $executedquery->execute(); }排查隐藏错误:
在PHP脚本开头添加错误输出代码,查看是否有未捕获的错误:error_reporting(E_ALL); ini_set('display_errors', 1);对比实际执行的SQL语句:
在PHP中执行查询前,打印最终生成的SQL语句,和Powershell中执行的语句对比,确认是否存在空格、大小写、特殊字符等差异。比如在execute()前添加:echo $queryused; die();
内容的提问来源于stack exchange,提问作者DevilBoy
相关产品推荐
相关产品推荐

