使用PHP MySQL进行Android登录和注册

时间:2020-02-23 14:29:03  来源:igfitidea点击:

Android登录和注册是非常常见的场景。
您会在所有需要用户信息的应用程序中找到注册和登录操作。
在本教程中,我们将设置本地Web服务器和MySQL数据库。
我们将开发android登录和注册应用程序。
我们将使用PHP脚本连接到MySQL数据库。

Android登录注册

第一步是创建后端Web服务器。
我在Mac OS X上工作,并且XAMPP可用于快速设置本地Apache Web服务器和MySQL数据库。

设置XAMPP服务器

XAMPP(或者WAMP)是一键式安装程序软件,可为开发PHP,MySQL Web应用程序(我们将与android应用程序连接)创建环境。

从这里下载并安装XAMPP。

安装后启动XAMPP应用程序,将会看到下面的屏幕。

您可以通过打开" https://localhost"来测试您的服务器。
应出现以下屏幕。

另外,您可以通过打开https://localhost/phpmyadmin来检查phpMyAdmin。

似乎MySQL服务器无法正常运行。
转到XAMPP应用程序中的"管理服务器"选项卡,然后单击"全部重新启动"。
如下图所示,服务器应正常运行。

现在在本地主机上测试phpMyAdmin,您将得到一个类似于此的屏幕。

现在,让我们测试一个示例php脚本。
创建一个新的test.php文件,并其中添加以下几行。

<?php
echo "Hello, World";
?>

在上面的代码中:

  • php开始为任何PHP脚本打开标签。

  • ?>表示结束标记,例如Java中的结束括号。

注意:本教程不是必须了解PHP。

如果您使用的是MAC,请转到"应用程序"->" Xampp"->" htdocs"。
在这里创建一个新文件夹,假设为test_android并复制粘贴之前创建的test.php。
现在打开URLhttps://localhost/test_android/test.php

您最终将看到如下屏幕:

设置MySQL数据库

通过访问https://localhost/phpmyadmin打开phpMyAdmin。
现在,选择标题行左上方的"数据库"标签。
给出一个随机名称并创建它。
新创建的空数据库将在左侧边列中可见。

让我们在新创建的数据库中创建一个用户表。
在控制台中运行以下查询

CREATE TABLE  `firstDB`.`users` (
  `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
  `username` VARCHAR( 20 ) NOT NULL ,
  `password` VARCHAR( 20 ) NOT NULL
)

将PHP连接到MySQL数据库

要将PHP脚本连接到MySQL数据库,需要三个输入值。
以下是输入以及XAMPP服务器的默认值

  • 主机名:localhost
  • MySQL用户名:root
  • MySQL密码:空白。

让我们创建一个test-connect.php脚本,并将其添加到htdocs-> test-android文件夹中。

<?php
$host="localhost";
$user="root";
$password="";
$con=mysql_connect($host,$user,$password);
if($con) {
  echo '<h1>Connected to MySQL</h1>';
} else {
  echo '<h1>MySQL Server is not connected</h1>';
}
?>

mysql_connect()是PHP的内置函数,可使用上述参数连接到MySQL数据库。

尝试运行https://localhost/test_android/test-connect.php并查看输出。
如果未连接,请尝试重新启动XAMPP服务器。

Android登录注册应用

现在,我们已经讨论了PHP和MySQL的基本设置,让我们进入android登录应用程序部分。
我们将开发一个登录/注册应用程序。
为了简单明了,我们将在注册过程中检查用户名和电子邮件是否唯一。
在进入应用逻辑之前,让我们先研究PHP脚本和MySQL数据库。

首先,让我们删除Table用户,并在上述应用程序的上下文中创建一个新用户。

CREATE TABLE IF NOT EXISTS `firstDB`.`users` (
`id` int(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`username` varchar(70) NOT NULL,
`password` varchar(40) NOT NULL,
`email` varchar(50) NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` datetime DEFAULT NULL

)

以下是您可以复制粘贴到htdocs-> test_android文件夹中的PHP脚本。

config.php

<?php
  define("DB_HOST", "localhost");
  define("DB_USER", "root");
  define("DB_PASSWORD", "");
  define("DB_NAME", "firstDB");
  ?>

下面给出了数据库连接的脚本。

db-connect.php

<?php
  
  include_once 'config.php';
  
  class DbConnect{
      
      private $connect;
      
      public function __construct(){
          
          $this->connect = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
          
          if (mysqli_connect_errno($this->connect)){
              echo "Unable to connect to MySQL Database: " . mysqli_connect_error();
          }
      }
      
      public function getDb(){
          return $this->connect;
      }
  }
  ?>

以下脚本包含应用程序的所有核心功能。

user.php

<?php
  
  include_once 'db-connect.php';
  
  class User{
      
      private $db;
      
      private $db_table = "users";
      
      public function __construct(){
          $this->db = new DbConnect();
      }
      
      public function isLoginExist($username, $password){
          
          $query = "select * from ".$this->db_table." where username = '$username' AND password = '$password' Limit 1";
          
          $result = mysqli_query($this->db->getDb(), $query);
          
          if(mysqli_num_rows($result) > 0){
              
              mysqli_close($this->db->getDb());
              
              
              return true;
              
          }
          
          mysqli_close($this->db->getDb());
          
          return false;
          
      }
      
      public function isEmailUsernameExist($username, $email){
          
          $query = "select * from ".$this->db_table." where username = '$username' AND email = '$email'";
          
          $result = mysqli_query($this->db->getDb(), $query);
          
          if(mysqli_num_rows($result) > 0){
              
              mysqli_close($this->db->getDb());
              
              return true;
              
          }
             
          return false;
          
      }
      
      public function isValidEmail($email){
          return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
      }
      
      public function createNewRegisterUser($username, $password, $email){
            
          $isExisting = $this->isEmailUsernameExist($username, $email);
          
          if($isExisting){
              
              $json['success'] = 0;
              $json['message'] = "Error in registering. Probably the username/email already exists";
          }
          
          else{
              
          $isValid = $this->isValidEmail($email);
              
              if($isValid)
              {
              $query = "insert into ".$this->db_table." (username, password, email, created_at, updated_at) values ('$username', '$password', '$email', NOW(), NOW())";
              
              $inserted = mysqli_query($this->db->getDb(), $query);
              
              if($inserted == 1){
                  
                  $json['success'] = 1;
                  $json['message'] = "Successfully registered the user";
                  
              }else{
                  
                  $json['success'] = 0;
                  $json['message'] = "Error in registering. Probably the username/email already exists";
                  
              }
              
              mysqli_close($this->db->getDb());
              }
              else{
                  $json['success'] = 0;
                  $json['message'] = "Error in registering. Email Address is not valid";
              }
              
          }
          
          return $json;
          
      }
      
      public function loginUsers($username, $password){
          
          $json = array();
          
          $canUserLogin = $this->isLoginExist($username, $password);
          
          if($canUserLogin){
              
              $json['success'] = 1;
              $json['message'] = "Successfully logged in";
              
          }else{
              $json['success'] = 0;
              $json['message'] = "Incorrect details";
          }
          return $json;
      }
  }
  ?>

在上面的代码中,$json包含返回的JSONObjects。

以下PHP脚本是首先从应用程序中调用的脚本。

index.php

<?php
  
  require_once 'user.php';
  
  $username = "";
  
  $password = "";
  
  $email = "";
  
  if(isset($_POST['username'])){
      
      $username = $_POST['username'];
      
  }
  
  if(isset($_POST['password'])){
      
      $password = $_POST['password'];
      
  }
  
  if(isset($_POST['email'])){
      
      $email = $_POST['email'];
      
  }
  
  $userObject = new User();
  
  //Registration
  
  if(!empty($username) && !empty($password) && !empty($email)){
      
      $hashed_password = md5($password);
      
      $json_registration = $userObject->createNewRegisterUser($username, $hashed_password, $email);
      
      echo json_encode($json_registration);
      
  }
  
  //Login
  
  if(!empty($username) && !empty($password) && empty($email)){
      
      $hashed_password = md5($password);
      
      $json_array = $userObject->loginUsers($username, $hashed_password);
      
      echo json_encode($json_array);
  }
  ?>

在上面的代码中,我们检查电子邮件字段是否为空。
如果是这样,我们将在PHP脚本中调用登录功能,否则,我们将转到注册功能。
JSON响应返回两个参数:success(0或者1)和消息。

  • " md5()"函数使用RSA Data Security,Inc. MD5消息摘要算法来创建密码的哈希字符串。

  • 为了检查电子邮件地址是否有效,我们实现了一个" isValidEmail()"方法。
    FILTER_VALIDATE_EMAIL适用于PHP版本5.2.0+

Android登录注册项目结构

在此项目中,我们使用了三个库来在我们的应用程序中实现HTTP调用。
JSONParser类用于对本地主机进行POST和GET HTTP调用,并以JSONObject的形式返回响应。

Android登录注册码

下面定义了" activity_main.xml"布局。

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:fillViewport="true">

  <RelativeLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content">

      <LinearLayout
          android:orientation="vertical"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_centerInParent="true"
          android:paddingLeft="24dp"
          android:paddingRight="24dp"
          android:id="@+id/linearLayout">

              <EditText android:id="@+id/editName"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:hint="Username"
                  android:textColor="#FF192133"
                  android:textColorHint="#A0192133"
                  android:fontFamily="sans-serif-light"
                  android:focusable="true"
                  android:focusableInTouchMode="true" 

              <EditText android:id="@+id/editPassword"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:inputType="textPassword"
                  android:textColor="#FF192133"
                  android:textColorHint="#A0192133"
                  android:fontFamily="sans-serif-light"
                  android:hint="Password"
                  android:focusable="true"
                  android:focusableInTouchMode="true" 

              <EditText android:id="@+id/editEmail"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:inputType="textEmailAddress"
                  android:textColor="#FF192133"
                  android:visibility="gone"
                  android:textColorHint="#A0192133"
                  android:fontFamily="sans-serif-light"
                  android:hint="Email"
                  android:focusable="true"
                  android:focusableInTouchMode="true" 

          <Button
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:id="@+id/btnSignIn"
              android:text="SIGN IN"
              android:textStyle="bold"
              

          <Button
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:id="@+id/btnRegister"
              android:text="REGISTER"
              android:textStyle="bold"
              

      </LinearLayout>

  </RelativeLayout>

</ScrollView>

MainActivity.java在下面给出。

package com.theitroad.loginphpmysql;

import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

  EditText editEmail, editPassword, editName;
  Button btnSignIn, btnRegister;

  String URL= "https://10.0.3.2/test_android/index.php";

  JSONParser jsonParser=new JSONParser();

  int i=0;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      editEmail=(EditText)findViewById(R.id.editEmail);
      editName=(EditText)findViewById(R.id.editName);
      editPassword=(EditText)findViewById(R.id.editPassword);

      btnSignIn=(Button)findViewById(R.id.btnSignIn);
      btnRegister=(Button)findViewById(R.id.btnRegister);

      btnSignIn.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View view) {
              AttemptLogin attemptLogin= new AttemptLogin();
              attemptLogin.execute(editName.getText().toString(),editPassword.getText().toString(),"");
          }
      });

      btnRegister.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View view) {

              if(i==0)
              {
                  i=1;
                  editEmail.setVisibility(View.VISIBLE);
                  btnSignIn.setVisibility(View.GONE);
                  btnRegister.setText("CREATE ACCOUNT");
              }
              else{

                  btnRegister.setText("REGISTER");
                  editEmail.setVisibility(View.GONE);
                  btnSignIn.setVisibility(View.VISIBLE);
                  i=0;

                  AttemptLogin attemptLogin= new AttemptLogin();
                  attemptLogin.execute(editName.getText().toString(),editPassword.getText().toString(),editEmail.getText().toString());

              }

          }
      });

  }

  private class AttemptLogin extends AsyncTask<String, String, JSONObject> {

      @Override

      protected void onPreExecute() {

          super.onPreExecute();

      }

      @Override

      protected JSONObject doInBackground(String... args) {

          String email = args[2];
          String password = args[1];
          String name= args[0];

          ArrayList params = new ArrayList();
          params.add(new BasicNameValuePair("username", name));
          params.add(new BasicNameValuePair("password", password));
          if(email.length()>0)
          params.add(new BasicNameValuePair("email",email));

          JSONObject json = jsonParser.makeHttpRequest(URL, "POST", params);

          return json;

      }

      protected void onPostExecute(JSONObject result) {

          //dismiss the dialog once product deleted
          //Toast.makeText(getApplicationContext(),result,Toast.LENGTH_LONG).show();

          try {
              if (result != null) {
                  Toast.makeText(getApplicationContext(),result.getString("message"),Toast.LENGTH_LONG).show();
              } else {
                  Toast.makeText(getApplicationContext(), "Unable to retrieve any data from server", Toast.LENGTH_LONG).show();
              }
          } catch (JSONException e) {
              e.printStackTrace();
          }

      }

  }
}

那是一个很大的代码!让我们从以上代码中得出重要的推论。

  • https://10.0.3.2是localhost重新路由地址。
    如果您使用的是Genymotion模拟器,则此地址专用。
    将https://10.0.2.2用于AVD模拟器,现在已大大改进。
    如果您使用计算机的WIFI地址在自己的设备上运行该应用程序,示例:https://192.168.0.143。

  • 单击"注册"按钮后,我们将以编程方式隐藏"登录"按钮并显示"电子邮件地址"输入文本字段。

  • AttemptLogin类在后台执行对本地主机的网络HTTP请求。

用户名密码和电子邮件参数将添加到通过makeHttpRequest(URL," POST",params)方法传递的ArrayList中; JSONParser类。

  • 在onPostExecute方法中,我们在Toast消息中显示从服务器返回的消息字符串。

下面给出了JSONParser.java类。

package com.theitroad.loginphpmysql;

import android.util.Log;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

/**
 * Created by anupamchugh on 29/08/16.
 */
public class JSONParser {

  static InputStream is = null;
  static JSONObject jObj = null;
  static JSONArray jArr = null;
  static String json = "";
  static String error = "";

  //constructor
  public JSONParser() {

  }

  //function get json from url
  //by making HTTP POST or GET mehtod
  public JSONObject makeHttpRequest(String url, String method,
                                    ArrayList params) {

      //Making HTTP request
      try {

          //check for request method
          if(method.equals("POST")){
              //request method is POST
              //defaultHttpClient
              HttpClient httpClient = new DefaultHttpClient();
              HttpPost httpPost = new HttpPost(url);
              httpPost.setEntity(new UrlEncodedFormEntity(params));
              try {
                  Log.e("API123", " " +convertStreamToString(httpPost.getEntity().getContent()));
                  Log.e("API123",httpPost.getURI().toString());
              } catch (Exception e) {
                  e.printStackTrace();
              }

              HttpResponse httpResponse = httpClient.execute(httpPost);
              Log.e("API123",""+httpResponse.getStatusLine().getStatusCode());
              error= String.valueOf(httpResponse.getStatusLine().getStatusCode());
              HttpEntity httpEntity = httpResponse.getEntity();
              is = httpEntity.getContent();

          }else if(method.equals("GET")){
              //request method is GET
              DefaultHttpClient httpClient = new DefaultHttpClient();
              String paramString = URLEncodedUtils.format(params, "utf-8");
              url += "?" + paramString;
              HttpGet httpGet = new HttpGet(url);

              HttpResponse httpResponse = httpClient.execute(httpGet);
              HttpEntity httpEntity = httpResponse.getEntity();
              is = httpEntity.getContent();
          }

      } catch (UnsupportedEncodingException e) {
          e.printStackTrace();
      } catch (ClientProtocolException e) {
          e.printStackTrace();
      } catch (IOException e) {
          e.printStackTrace();
      }

      try {
          BufferedReader reader = new BufferedReader(new InputStreamReader(
                  is, "iso-8859-1"), 8);
          StringBuilder sb = new StringBuilder();
          String line = null;
          while ((line = reader.readLine()) != null) {
              sb.append(line + "\n");
          }
          is.close();
          json = sb.toString();
          Log.d("API123",json);
      } catch (Exception e) {
          Log.e("Buffer Error", "Error converting result " + e.toString());
      }

      //try to parse the string to a JSON object
      try {
          jObj = new JSONObject(json);
          jObj.put("error_code",error);
      } catch (JSONException e) {
          Log.e("JSON Parser", "Error parsing data " + e.toString());
      }

      //return JSON String
      return jObj;

  }

  private String convertStreamToString(InputStream is) throws Exception {
      BufferedReader reader = new BufferedReader(new InputStreamReader(is));
      StringBuilder sb = new StringBuilder();
      String line = null;
      while ((line = reader.readLine()) != null) {
          sb.append(line);
      }
      is.close();
      return sb.toString();
  }
}

在上面的代码中,我们根据在makeHttpRequest函数中传递的第二个参数来调用相应的类HTTPPost或者HTTPGet。

jObj.put("error_code",error);

上面,我们将服务器返回的响应状态代码附加在返回给MainActivity类的最终JSONObject中。

注意:不要忘记在AndroidManifest.xml文件中添加以下权限。

<uses-permission android:name="android.permission.INTERNET"

许多用户已在本教程的底部发布了他们的注释,指出他们正在"无法检索数据" Toast。
请注意,从Android 6.0及更高版本开始,您需要在Manifest.xml文件的应用程序标记中添加以下属性:

android:usesCleartextTraffic =" true""

为什么这样?为了允许仿真器/设备的网络安全进行http调用。

请使用以下来自Android Q仿真器的最新屏幕抓图检查输出。
链接和我们的Github存储库中更新了具有AndroidManifest.xml文件中的更改的最新源代码。

实际应用程序的输出如下。

Android注册用户

在下面的屏幕截图中,我们注册了一个新用户,并将其添加到数据库中。
然后,我们使用在注册过程中输入的凭据登录。

Android登录与Php Mysql最终输出

这结束了使用PHP MySQL教程的Android登录。
您可以从下面的链接下载项目。
它还包含test_android文件夹,其中包含PHP文件。
将其复制到xampp-> htdocs文件夹中!