Java Android显示来自PHP的数据,这些数据将表彼此链接起来
我目前正在努力研究如何正确显示PHP中链接到另一个表的表的详细信息。现在我的Android代码有多个显示不同细节的片段,我可以将这些信息从php显示到Android代码中,但是当我登录用户名时,这些细节的显示方式不同 假设我有配置文件片段、平衡片段和记录片段。现在,当我登录到给定的用户名时,这些片段将显示其他用户详细信息 此外,在我的PHP服务器中,我创建了3个表,每个表都相互链接。在我的PHP代码中,我为每个表创建单独的文件,因为我遵循internet上的一些指南,可以从PHP获取数据 表1: 表2 这是balance.php代码:Java Android显示来自PHP的数据,这些数据将表彼此链接起来,java,php,android,mysql,android-fragments,Java,Php,Android,Mysql,Android Fragments,我目前正在努力研究如何正确显示PHP中链接到另一个表的表的详细信息。现在我的Android代码有多个显示不同细节的片段,我可以将这些信息从php显示到Android代码中,但是当我登录用户名时,这些细节的显示方式不同 假设我有配置文件片段、平衡片段和记录片段。现在,当我登录到给定的用户名时,这些片段将显示其他用户详细信息 此外,在我的PHP服务器中,我创建了3个表,每个表都相互链接。在我的PHP代码中,我为每个表创建单独的文件,因为我遵循internet上的一些指南,可以从PHP获取数据 表1:
<?php
define('HOST','localhost');
define('USER','root');
define('PASS','');
define('DB','ips');
$con = mysqli_connect(HOST,USER,PASS,DB);
$sql = "select * from account_details";
$res = mysqli_query($con,$sql);
$result = array();
$row = mysqli_fetch_assoc($res);
array_push($result,
array(
"Balance"=>$row['Balance'],
));
echo json_encode(array("result"=>$result));
mysqli_close($con);
?>
我试着运行php文件,它给了我空值
{
"result": [{
"Balance": null
}]
}
已编辑balance.php代码版本3
<?php
define('HOST','localhost');
define('USER','root');
define('PASS','');
define('DB','ips');
$Username = $_GET["Username"];
$mysqli = mysqli_connect(HOST,USER,PASS,DB);
$stmt = $mysqli->prepare ("SELECT Balance from account_details WHERE
Username=?");
$stmt->bind_param('s', $Username);
$stmt->execute();
$stmt->bind_result($Balance);
$rows = array();
while($stmt->fetch()) {
array_push($rows, array('Balance'=>$Balance));
}
$stmt->close();
$mysqli->close();
echo json_encode($rows);
?>
好的,我已经成功地在PHP中加入了这个表,并且可以得到我想要的结果。现在我试着运行我的Android代码,当我点击显示数据时,它崩溃了,我如何更正代码?为了完整性和总结评论对话,这里是所需的修复。原始基于PHP的JSON端点中的SQL查询没有WHERE子句,因此它们会将整个表传递给移动应用程序,而不是所需的记录 此外,每个端点请求中都不需要安全详细信息,因此internet上的任何人都可以检索任何数据,只要他们拥有用户名。我们在这里添加了一个密码,并建议作为未来工作的一项,该应用程序包括一个凭据对话框和适当的本地存储,以便用户能够识别自己 存在一个SQL注入漏洞,通过MySQLi驱动程序中的参数绑定修复了该漏洞 需要注意的是,密码不应以明文形式存储。这里需要一个同时在Java和PHP中工作的哈希系统 建议的改进 您可能需要考虑如何实现这些功能: 连接应始终通过HTTPS,如果端点是HTTP安全的,则应用程序应拒绝连接这些天证书是免费的, 应该有一个速率限制器,这样用户每分钟只能获得一定次数的尝试,以防止暴力攻击, 应该有一些IP阻塞,所以某个IP的失败尝试太多会将其锁定一段时间, 应该有一个系统来强制执行最小密码长度和复杂性。
当您的应用程序连接到PHP服务器时,看起来您正在一次检索每个表中的所有记录。通常,您必须发送用户名、哈希和/或密码等标识符,以便返回正确的记录。我想知道修复这个问题是否是一个好的开始。Pro-tips:a您不需要在数据库中存储确认密码-这只是确保用户正确键入密码的一种方法。创建记录时,要求两次,确保它们相同,然后存储一次。b不要以明文形式存储密码,这会使您的用户容易受到二次重用攻击。我知道这是一个家庭作业,所以你不会用它来做任何有价值的事情,但了解这是一个漏洞是很有价值的。要获取相关记录,你需要一个JSON端点,该端点在其选择代码中使用JOIN。在搜索引擎中搜索与SQL JOIN相关的记录。@halfer我知道纯文本密码,目前不是问题,但现在我已经添加/编辑了balance php文件,但它给了我空值OK,该文件中存在SQL注入漏洞,因此需要修复。如果您得到一个空值,则表示您有一个数据库错误,或者您的搜索没有返回任何记录。由于这是一个GET操作,您可以在浏览器中调试它,所以我建议您首先进行调试。查阅http://localhost/balance.php?Username=myname. 但是,我看不到$Username来自何处-您需要使用$\u GET['Username']从查询字符串中读取它。
public class dri_balance extends ArrayAdapter<String> {
private String[] Acc_Balance;
private Activity context;
public dri_balance(Activity context, String[] Acc_Balance) {
super(context, R.layout.fragment_balance, Acc_Balance);
this.context = context;
this.Acc_Balance = Acc_Balance;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View listViewItem = inflater.inflate(R.layout.fragment_balance, null,
true);
TextView tvBlnf = (TextView) listViewItem.findViewById(R.id.tvBlnf);
tvBlnf.setText(Acc_Balance[position]);
return listViewItem;
}
}
public class BalanceFragment extends Fragment implements
View.OnClickListener {
public BalanceFragment() {
// Required empty public constructor
}
public static final String JSON_URL =
"http://192.168.1.2/json_balance_records.php";
private Button buttonGet;
private ListView listView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.activity_listview, container,
false);
buttonGet = (Button) rootView.findViewById(R.id.buttonGet);
buttonGet.setOnClickListener(this);
listView = (ListView) rootView.findViewById(R.id.listView);
return rootView;
//return inflater.inflate(R.layout.fragment_profile, container, false);
}
private void sendRequest(){
StringRequest stringRequest = new StringRequest(JSON_URL, new
Response.Listener<String>() {
@Override
public void onResponse(String response) {
showJSON(response);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getActivity().getApplicationContext(),error.getMessage(),
Toast.LENGTH_LONG).show();
}
});
RequestQueue requestQueue =
Volley.newRequestQueue(getActivity().getApplicationContext());
requestQueue.add(stringRequest);
}
private void showJSON(String json){
Dri_Balance pj = new Dri_Balance(json);
pj.parseJSON();
dri_balance cl = new dri_balance(getActivity(),
Dri_Balance.Acc_Balance);
listView.setAdapter(cl);
}
@Override
public void onClick(View v) {
sendRequest();
}
}
public class Dri_Balance {
public static String[] Acc_Balance;
public static final String JSON_ARRAY = "result";
public static final String KEY_DriBalance = "Acc_Balance";
private JSONArray users = null;
private String json;
public Dri_Balance(String json){
this.json = json;
}
public void parseJSON(){
JSONObject jsonObject=null;
try {
jsonObject = new JSONObject(json);
users = jsonObject.getJSONArray(JSON_ARRAY);
Acc_Balance = new String[users.length()];
for(int i=0;i<users.length();i++){
JSONObject jo = users.getJSONObject(i);
Acc_Balance[i] = jo.getString(KEY_DriBalance);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
define('HOST','localhost');
define('USER','root');
define('PASS','');
define('DB','ips');
$con = mysqli_connect(HOST,USER,PASS,DB);
$sql = "select Balance from account_details WHERE Username='$Username'";
$res = mysqli_query($con,$sql);
$result = array();
$row = mysqli_fetch_assoc($res);
array_push($result,
array(
"Balance"=>$row['Balance'],
));
echo json_encode(array("result"=>$result));
mysqli_close($con);
?>
{
"result": [{
"Balance": null
}]
}
<?php
define('HOST','localhost');
define('USER','root');
define('PASS','');
define('DB','ips');
$Username = $_GET["Username"];
$mysqli = mysqli_connect(HOST,USER,PASS,DB);
$stmt = $mysqli->prepare ("SELECT Balance from account_details WHERE
Username=?");
$stmt->bind_param('s', $Username);
$stmt->execute();
$stmt->bind_result($Balance);
$rows = array();
while($stmt->fetch()) {
array_push($rows, array('Balance'=>$Balance));
}
$stmt->close();
$mysqli->close();
echo json_encode($rows);
?>
[{"Balance":"50.512"}]