Java Android显示来自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中链接到另一个表的表的详细信息。现在我的Android代码有多个显示不同细节的片段,我可以将这些信息从php显示到Android代码中,但是当我登录用户名时,这些细节的显示方式不同

假设我有配置文件片段、平衡片段和记录片段。现在,当我登录到给定的用户名时,这些片段将显示其他用户详细信息

此外,在我的PHP服务器中,我创建了3个表,每个表都相互链接。在我的PHP代码中,我为每个表创建单独的文件,因为我遵循internet上的一些指南,可以从PHP获取数据

表1:

表2

这是balance.php代码:

<?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"}]