简体   繁体   English

使用Volley库未从Android收到PHP POST

[英]PHP POST not received from Android using Volley library

I made a post request with the following code in Android using Volley. 我使用Volley在Android中使用以下代码发出了发布请求。

JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Method.POST, ServerURL.URL_REGISTER, new Response.Listener<JSONObject>() {

    @Override
    public void onResponse(JSONObject response) {
        Log.d(TAG_REGISTER, "Register Response: " + response.toString());
        pDialog.dismiss();

        try {
            JSONObject jObj = new JSONObject(response.toString());
            boolean error = jObj.getBoolean("error");
            if (!error) {
                // User successfully stored in MySQL
                // Now store the user in sqlite
                String uid = jObj.getString("uid");

                JSONObject user = jObj.getJSONObject("user");
                String name = user.getString("name");
                String email = user.getString("email");
                String created_at = user
                        .getString("created_at");

                // Inserting row in users table
                db.addUserIntoSQLite(name, email, uid, created_at);

                Toast.makeText(getActivity(), "User successfully registered. Try login now!", Toast.LENGTH_LONG).show();

                // Launch main activity
                Intent intent = new Intent(getActivity(), MainActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
                getActivity().overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
                startActivity(intent);
                getActivity().finish();

            } else {

                // Error occurred in registration. Get the error
                // message
                String errorMsg = jObj.getString("error_msg");
                Toast.makeText(getActivity(), errorMsg, Toast.LENGTH_LONG).show();
            }
        } catch (JSONException e) {
            Toast.makeText(getActivity(), "JSONException: " + e.getMessage(), Toast.LENGTH_LONG).show();
        }

    }
}, new Response.ErrorListener() {

    @Override
    public void onErrorResponse(VolleyError error) {
        Log.e(TAG_REGISTER, "Registration Error: " + error.getMessage());
        Toast.makeText(getActivity(), error.getMessage(), Toast.LENGTH_LONG).show();
        pDialog.dismiss();
    }
}) {

    @Override
    public String getBodyContentType() {
        return "application/json; charset=utf-8";
    }

    @Override
    protected Map<String, String> getParams() throws AuthFailureError {
        HashMap<String, String> params = new HashMap<>();
        params.put("tag", "register");
        params.put("name", name);
        params.put("email", email);
        params.put("password", password);
        return params;
    }
};

Now here's the PHP part that receives the post request and get the post values. 现在,这里是PHP部分,用于接收发布请求并获取发布值。

<?php
session_start();

if (!empty($_POST['tag'])) {

    // get tag
    $tag = $_POST['tag'];

    // include db handler
    require_once 'mysql/DB_Functions.php';
    $db = new DB_Functions();

    // response Array
    $response = array("tag" => $tag, "error" => FALSE);

    // check for tag type
    if ($tag == 'login') {
        // Request type is check Login
        $email = $_POST['email'];
        $password = $_POST['password'];

        // check for user
        $user = $db->getUserByEmailAndPassword($email, $password);
        if ($user != false) {
            // user found
            $response["error"] = FALSE;
            $response["uid"] = $user["unique_id"];
            $response["user"]["name"] = $user["name"];
            $response["user"]["email"] = $user["email"];
            $response["user"]["created_at"] = $user["created_at"];
            $response["user"]["updated_at"] = $user["updated_at"];
            echo json_encode($response);
        } else {
            // user not found
            // echo json with error = 1
            $response["error"] = TRUE;
            $response["error_msg"] = "Incorrect email or password!";
            echo json_encode($response);
        }
    } else if ($tag == 'register') {
        // Request type is Register new user
        $name = $_POST['name'];
        $email = $_POST['email'];
        $password = $_POST['password'];

        // check if user is already existed
        if ($db->userExists($email)) {
            // user is already existed - error response
            $response["error"] = TRUE;
            $response["error_msg"] = "User already exists";
            echo json_encode($response);
        } else {
            // store user
            $user = $db->storeUser($name, $email, $password);
            if ($user) {
                // user stored successfully
                $response["error"] = FALSE;
                $response["uid"] = $user["unique_id"];
                $response["user"]["name"] = $user["name"];
                $response["user"]["email"] = $user["email"];
                $response["user"]["created_at"] = $user["created_at"];
                $response["user"]["updated_at"] = $user["updated_at"];
                echo json_encode($response);
            } else {
                // user failed to store
                $response["error"] = TRUE;
                $response["error_msg"] = "Error occured in Registartion";
                echo json_encode($response);
            }
        }
    } else {
        // user failed to store
        $response["error"] = TRUE;
        $response["error_msg"] = "Unknow 'tag' value. It should be either 'login' or 'register'";
        echo json_encode($response);
    }
} else {
    $response["error"] = TRUE;
    $response["error_msg"] = "Operation failed due to the missing tag!";
    echo json_encode($response);
}

var_dump($_SERVER['REQUEST_METHOD'], $_POST);
?>

I should be able to get the 'tag' value, but the problem is that it keeps saying that the 'tag' is missing. 我应该能够获得“标签”值,但问题是它一直在说“标签”缺失。

So now I created an HTML file to test which part has a problem. 因此,现在我创建了一个HTML文件来测试哪个部分有问题。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="index.php" method="post">
Tag: <input type="text" name="tag"><br>
Name: <input type="text" name="name"><br>
Email: <input type="text" name="email"><br>
Password: <input type="password" name="password"><br>
<input type="submit">
</form>
</body>
</html>

As I put the data in this HTML file, the data is successfully stored in the MySQL database. 当我将数据放入此HTML文件时,数据已成功存储在MySQL数据库中。 Which part do you think has the problem? 您认为哪一部分有问题?

I've searched all the solutions regarding the Volley part, and my Volley part doesn't seem to have the problem. 我搜索了有关Volley部分的所有解决方案,而我的Volley部分似乎没有问题。 So I believe it's the PHP part that's causing the issue. 因此,我相信是导致问题的PHP部分。

If I open the PHP file on the web, it shows the following message. 如果我在网上打开PHP文件,它将显示以下消息。

{"error":true,"error_msg":"Operation failed due to the missing tag!"}string(3) "GET" array(0) { }

The problem is that you are sending data from the Volley library as content type application/json but your PHP script is expecting POST data as content type application/x-www-form-urlencoded . 问题是您正在以内容类型application/json从Volley库发送数据,但是您的PHP脚本期望以内容类型application/x-www-form-urlencoded POST数据。 This is why your POST from the web form worked, but your POST from Volley did not. 这就是为什么您可以通过Web表单进行POST的方法,但不能使用Volley进行的POST。

In your PHP script, do this: 在您的PHP脚本中,执行以下操作:

$data = json_decode(file_get_contents('php://input'), true);

if (empty($data['tag']) == false) {
    $tag = $data['tag'];
    echo $tag;
}

Because you're sending the data as JSON, PHP won't automatically parse it into the $_POST global. 因为您将数据作为JSON发送,所以PHP不会自动将其解析为$ _POST全局变量。 What the code above does is get the raw POST data as a string and parse it into an array. 上面的代码所做的是将原始POST数据作为字符串获取,并将其解析为数组。

Update 更新资料

I spent some more time debugging this and now have a full solution: 我花了更多时间调试它,现在有了完整的解决方案:

PHP: PHP:

Change your script to access the raw POST data using the method I listed above, instead of $_POST global. 使用上面列出的方法(而不是$ _POST全局)更改脚本以访问原始POST数据。 Use this code for debugging purposes: 将此代码用于调试目的:

<?php

$data = json_decode(file_get_contents('php://input'), true);

if (empty($data['tag']) == false) {
    $tag = $data['tag'];
}

echo json_encode([ "tag" => $tag ]);
?>

Android : 安卓

getParams() is apparently not used with JsonObjectRequest class, so your body is empty. getParams()显然未与JsonObjectRequest类一起JsonObjectRequest ,因此您的身体为空。 See the answer to this question for details of that . 有关此问题的详细信息,请参见此问题的答案 Instead, you must pass your body as a JsonObject in the constructor to JsonObjectRequest . 相反,您必须在构造函数中将您的身体作为JsonObject传递给JsonObjectRequest For example: 例如:

    HashMap<String, String> params = new HashMap<>();
    params.put("tag", "register");
    params.put("name", "myname");
    params.put("email", "myname@email.com");
    params.put("password", "meow");
    JSONObject o = new JSONObject(params);
    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
        Request.Method.POST, 
        ServerURL.URL_REGISTER, 
        o, 
        new Response.Listener<JSONObject>() { // ... 

Result : 结果

D/EXAMPLE: Register Response: {"tag":"register"} D / EXAMPLE:注册响应:{“ tag”:“ register”}

I've created a more complete example as a gist . 我已经创建了一个更完整的示例作为要点

Note: If you are making requests to a development server on your local machine, you'll need to use 10.0.2.2:PORT instead of localhost:PORT. 注意:如果要向本地计算机上的开发服务器发出请求,则需要使用10.0.2.2:PORT而不是localhost:PORT。 I'm assuming that this is not an issue in your case, since you seem able to connect to your server, but include this note for completeness for any future readers. 我假设这对您来说不是问题,因为您似乎可以连接到服务器,但是请包含此注释以确保将来的读者阅读完整。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM