Paramclasses Academy - Blog

Tutorials Details

←
Post 24 of 39
→

How to Connect a React Native App to PHP and MySQL Backend ?

How to Connect a React Native App to PHP and MySQL Backend ?

November 5, 2026

1. Introduction

Most professional mobile applications need a backend server and database to store information permanently.

For example:

  • A student management application stores student records.

  • A shopping application stores product and order information.

  • A school application stores student attendance and fees.

  • A banking application retrieves account information.

  • An employee application stores employee details.

React Native handles the mobile application interface, PHP handles backend processing, and MySQL stores the information.

In this tutorial, we will connect all three technologies and build a practical Student Management System.

We will learn how to:

  1. Create a MySQL database.

  2. Create a students table.

  3. Connect PHP to MySQL.

  4. Create a PHP REST API.

  5. Retrieve data from PHP using React Native.

  6. Insert new student records.

  7. Update existing student records.

  8. Delete student records.

  9. Handle API responses and errors.

  10. Test the complete application.

2. Understand React Native, PHP and MySQL Architecture

Before writing code, understand how these technologies communicate.

Our application will follow this architecture:

       REACT NATIVE APP
              |
              |
         FETCH API
              |
              |
        HTTP REQUEST
              |
              |
         PHP BACKEND
              |
              |
         PDO CONNECTION
              |
              |
         MYSQL DATABASE
              |
              |
         PHP BACKEND
              |
              |
        JSON RESPONSE
              |
              |
       REACT NATIVE APP

Role of Each Technology

React Native

  • Creates the mobile application interface.

  • Collects student information.

  • Sends API requests.

  • Displays records received from the server.

PHP

  • Receives HTTP requests.

  • Validates input information.

  • Executes database operations.

  • Returns JSON responses.

MySQL

  • Stores student records.

  • Retrieves student information.

  • Updates existing records.

  • Deletes records.

Important: React Native should not connect directly to MySQL. PHP acts as the backend layer between the mobile application and database.

3. Requirements for This Tutorial

Install or prepare the following software:

  1. Node.js and npm.

  2. Visual Studio Code.

  3. React Native with Expo.

  4. Android Studio or Expo Go.

  5. XAMPP.

  6. PHP.

  7. MySQL.

  8. phpMyAdmin.

We will use XAMPP for our PHP and MySQL development environment.

4. Start XAMPP

Open the XAMPP Control Panel.

Start these two services:

  • Apache

  • MySQL

<escape> </escape>

Both services should show that they are running.

Now open your browser and visit:

http://localhost/

If the XAMPP dashboard opens, Apache is working.

Now visit:

http://localhost/phpmyadmin/

If phpMyAdmin opens, you can manage your MySQL databases.

Important: If Apache or MySQL is already running on another port, use the configured port in your API URL.

5. Create a MySQL Database

Now we will create a database for our Student Management Application.

Open phpMyAdmin:

http://localhost/phpmyadmin/

Follow these steps:

  1. Open phpMyAdmin.

  2. Click the SQL tab.

  3. Enter the following query.

  4. Click Go.

SQL Query

CREATE DATABASE student_api_db;

Our database name is:

student_api_db

6. Create a Students Table

Now select the student_api_db database.

Open the SQL tab and execute:

CREATE TABLE students (

    id INT AUTO_INCREMENT PRIMARY KEY,

    name VARCHAR(100) NOT NULL,

    email VARCHAR(150) NOT NULL,

    course VARCHAR(100) NOT NULL,

    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

);

Understand the Table Structure

Column Purpose
id Unique student ID
name Student name
email Student email
course Course name
created_at Record creation time

The AUTO_INCREMENT property automatically generates a unique ID for each student.

The database structure is now ready.

7. Insert Sample Student Records

Let's add two sample records to our database.

Execute:

INSERT INTO students
(name, email, course)
VALUES
('Rahul Sharma', 'rahul@gmail.com', 'React Native'),
('Amit Kumar', 'amit@gmail.com', 'JavaScript');

Now execute:

SELECT * FROM students;

You should see the two student records in phpMyAdmin.

8. Create a PHP API Project

Now we will create the backend API using PHP.

Open your XAMPP installation directory.

On Windows, it is commonly:

C:\xampp\htdocs\

Inside the htdocs folder, create a new folder:

student_api

Our folder structure will look like this:

C:\xampp\htdocs\

    student_api/

        db.php

        students.php

Explanation:

  • db.php will connect PHP to MySQL.

  • students.php will handle student CRUD operations.

9. Connect PHP to MySQL Using PDO

Open Visual Studio Code.

Open the student_api folder.

Create a file named:

db.php

Add the following code:

Complete db.php Code

<?php

$host = "localhost";

$dbname = "student_api_db";

$username = "root";

$password = "";

try {

    $pdo = new PDO(

        "mysql:host=$host;dbname=$dbname;charset=utf8mb4",

        $username,

        $password

    );

    $pdo->setAttribute(
        PDO::ATTR_ERRMODE,
        PDO::ERRMODE_EXCEPTION
    );

    $pdo->setAttribute(
        PDO::ATTR_DEFAULT_FETCH_MODE,
        PDO::FETCH_ASSOC
    );

} catch (PDOException $e) {

    http_response_code(500);

    header("Content-Type: application/json");

    echo json_encode([
        "success" => false,
        "message" => "Database connection failed"
    ]);

    exit;

}

?>

Understand the Code

1. Database host

$host = "localhost";

The MySQL server is running on the same computer as XAMPP.

2. Database name

$dbname = "student_api_db";

This is the database we created in phpMyAdmin.

3. Database username

$username = "root";

The default XAMPP MySQL username is commonly root.

4. Database password

$password = "";

A default XAMPP installation commonly uses an empty password. If your MySQL installation has a password, enter the correct password.

5. Create PDO connection

$pdo = new PDO(
    "mysql:host=$host;dbname=$dbname;charset=utf8mb4",
    $username,
    $password
);

PDO creates a connection between PHP and MySQL.

6. Enable exception handling

$pdo->setAttribute(
    PDO::ATTR_ERRMODE,
    PDO::ERRMODE_EXCEPTION
);

This allows PHP to handle database errors using exceptions.

10. Create a PHP REST API

Now create another file:

students.php

This file will handle all four CRUD operations.

CRUD stands for:

  • Create – Insert a student.

  • Read – Retrieve student records.

  • Update – Modify student information.

  • Delete – Remove a student record.

We will use HTTP methods:

HTTP Method Operation
GET Retrieve students
POST Add student
PUT Update student
DELETE Delete student

Our API endpoint will be:

http://localhost/student_api/students.php

Complete PHP REST API Code

Add this code inside students.php:

<?php

header("Content-Type: application/json");

require_once "db.php";

function sendResponse($success, $message, $data = null, $status = 200) {

    http_response_code($status);

    echo json_encode([
        "success" => $success,
        "message" => $message,
        "data" => $data
    ]);

    exit;

}

$method = $_SERVER["REQUEST_METHOD"];

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

if (!is_array($input)) {
    $input = [];
}

try {

    // GET: Retrieve students

    if ($method === "GET") {

        if (isset($_GET["id"])) {

            $id = filter_var(
                $_GET["id"],
                FILTER_VALIDATE_INT
            );

            if (!$id || $id < 1) {
                sendResponse(
                    false,
                    "Invalid student ID",
                    null,
                    400
                );
            }

            $stmt = $pdo->prepare(
                "SELECT * FROM students WHERE id = ?"
            );

            $stmt->execute([$id]);

            $student = $stmt->fetch();

            if (!$student) {
                sendResponse(
                    false,
                    "Student not found",
                    null,
                    404
                );
            }

            sendResponse(
                true,
                "Student retrieved successfully",
                $student
            );

        }

        $stmt = $pdo->query(
            "SELECT * FROM students ORDER BY id DESC"
        );

        $students = $stmt->fetchAll();

        sendResponse(
            true,
            "Students retrieved successfully",
            $students
        );

    }

    // POST: Add student

    elseif ($method === "POST") {

        $name = trim($input["name"] ?? "");

        $email = trim($input["email"] ?? "");

        $course = trim($input["course"] ?? "");

        if (
            $name === "" ||
            $email === "" ||
            $course === ""
        ) {

            sendResponse(
                false,
                "All fields are required",
                null,
                422
            );

        }

        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {

            sendResponse(
                false,
                "Invalid email address",
                null,
                422
            );

        }

        $stmt = $pdo->prepare(

            "INSERT INTO students
            (name, email, course)
            VALUES (?, ?, ?)"

        );

        $stmt->execute([
            $name,
            $email,
            $course
        ]);

        $id = $pdo->lastInsertId();

        sendResponse(
            true,
            "Student added successfully",
            [
                "id" => $id,
                "name" => $name,
                "email" => $email,
                "course" => $course
            ],
            201
        );

    }

    // PUT: Update student

    elseif ($method === "PUT") {

        $id = filter_var(
            $input["id"] ?? null,
            FILTER_VALIDATE_INT
        );

        $name = trim($input["name"] ?? "");

        $email = trim($input["email"] ?? "");

        $course = trim($input["course"] ?? "");

        if (!$id || $id < 1) {

            sendResponse(
                false,
                "Valid student ID is required",
                null,
                422
            );

        }

        if (
            $name === "" ||
            $email === "" ||
            $course === ""
        ) {

            sendResponse(
                false,
                "All fields are required",
                null,
                422
            );

        }

        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {

            sendResponse(
                false,
                "Invalid email address",
                null,
                422
            );

        }

        $stmt = $pdo->prepare(

            "UPDATE students
            SET name = ?, email = ?, course = ?
            WHERE id = ?"

        );

        $stmt->execute([
            $name,
            $email,
            $course,
            $id
        ]);

        if ($stmt->rowCount() === 0) {

            $check = $pdo->prepare(
                "SELECT id FROM students WHERE id = ?"
            );

            $check->execute([$id]);

            if (!$check->fetch()) {

                sendResponse(
                    false,
                    "Student not found",
                    null,
                    404
                );

            }

        }

        sendResponse(
            true,
            "Student updated successfully",
            [
                "id" => $id,
                "name" => $name,
                "email" => $email,
                "course" => $course
            ]
        );

    }

    // DELETE: Delete student

    elseif ($method === "DELETE") {

        $id = filter_var(
            $input["id"] ?? null,
            FILTER_VALIDATE_INT
        );

        if (!$id || $id < 1) {

            sendResponse(
                false,
                "Valid student ID is required",
                null,
                422
            );

        }

        $stmt = $pdo->prepare(
            "DELETE FROM students WHERE id = ?"
        );

        $stmt->execute([$id]);

        if ($stmt->rowCount() === 0) {

            sendResponse(
                false,
                "Student not found",
                null,
                404
            );

        }

        sendResponse(
            true,
            "Student deleted successfully"
        );

    }

    else {

        sendResponse(
            false,
            "Method not allowed",
            null,
            405
        );

    }

} catch (PDOException $e) {

    error_log($e->getMessage());

    sendResponse(
        false,
        "Database operation failed",
        null,
        500
    );

} catch (Throwable $e) {

    error_log($e->getMessage());

    sendResponse(
        false,
        "Internal server error",
        null,
        500
    );

}

?>

Understand the Important PHP Concepts

A. Read HTTP method

$method = $_SERVER["REQUEST_METHOD"];

This identifies whether the mobile application sent GET, POST, PUT or DELETE.

B. Read JSON request data

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

This reads the JSON body sent by React Native and converts it into a PHP associative array.

C. Use prepared statements

$stmt = $pdo->prepare(
    "INSERT INTO students (name, email, course)
     VALUES (?, ?, ?)"
);

Prepared statements help protect database queries from SQL injection when user-provided values are bound as parameters.

D. Return JSON

echo json_encode([
    "success" => true,
    "message" => "Student added successfully"
]);

PHP converts the response array into JSON so React Native can read it.

11. Test the PHP API in a Browser

Before connecting React Native, test the PHP backend.

Open:

http://localhost/student_api/students.php

You should receive a JSON response similar to:

{
  "success": true,
  "message": "Students retrieved successfully",
  "data": [
    {
      "id": 2,
      "name": "Amit Kumar",
      "email": "amit@gmail.com",
      "course": "JavaScript"
    },
    {
      "id": 1,
      "name": "Rahul Sharma",
      "email": "rahul@gmail.com",
      "course": "React Native"
    }
  ]
}

If the response appears, the PHP API can retrieve information from MySQL.

A browser address bar normally sends GET requests. To test POST, PUT and DELETE, use Postman or another HTTP API client.

12. Understand Localhost in React Native

This is one of the most important parts of the tutorial.

When React Native runs on an Android emulator, localhost does not mean your computer.

For the Android Studio emulator, use:

http://10.0.2.2/

Therefore, our API URL becomes:

http://10.0.2.2/student_api/students.php

Different Development Environments

Environment API host
Computer browser localhost
Android Studio emulator 10.0.2.2
Physical Android phone Computer's LAN IP
Deployed backend Public server domain

For a physical phone:

  1. Connect the phone and computer to the same Wi-Fi network.

  2. Find your computer's local IPv4 address.

  3. Replace the host with that IP.

Example:

http://192.168.1.5/student_api/students.php

Replace this example IP with your computer's actual local IP.

Also ensure that the firewall allows incoming connections to the Apache port.

Important: Do not use 10.0.2.2 on a physical Android phone. It is the special host address for the standard Android Studio emulator.

13. Create a React Native Project

Open a new terminal.

Execute:

npx create-expo-app@latest StudentPHPApp --template blank

Navigate into the project:

cd StudentPHPApp

Open Visual Studio Code:

code .

Start the Expo server:

npx expo start

We will use Fetch API, so no additional HTTP library is required.

14. Connect React Native to the PHP API

Open App.js.

First, import the components:

import React, { useEffect, useState } from "react";

import {
  View,
  Text,
  TextInput,
  Pressable,
  FlatList,
  StyleSheet,
  Alert,
  ActivityIndicator,
} from "react-native";

Step 1: Configure API URL

Add this above the App component:

const API_URL =
  "http://10.0.2.2/student_api/students.php";

If you are using a physical phone, replace 10.0.2.2 with your computer's LAN IP.

If your Apache server uses a different port, include that port in the URL.

Step 2: Create State Variables

Inside the App component:

const [students, setStudents] = useState([]);

const [name, setName] = useState("");

const [email, setEmail] = useState("");

const [course, setCourse] = useState("");

const [loading, setLoading] = useState(false);

const [editingId, setEditingId] = useState(null);

Explanation:

  • students stores student records.

  • name stores the student name.

  • email stores the student email.

  • course stores the course.

  • loading controls the loading indicator.

  • editingId identifies the student currently being edited.

Step 3: Create a GET API Function

This function retrieves student records from PHP.

const fetchStudents = async () => {

  try {

    setLoading(true);

    const response = await fetch(API_URL);

    const result = await response.json();

    if (!response.ok || !result.success) {

      throw new Error(
        result.message || "Unable to load students"
      );

    }

    setStudents(result.data);

  } catch (error) {

    Alert.alert("Error", error.message);

  } finally {

    setLoading(false);

  }

};

Explanation:

  1. Fetch sends a GET request.

  2. PHP retrieves records from MySQL.

  3. PHP returns JSON.

  4. React Native parses the JSON response.

  5. setStudents() updates the screen.

Step 4: Load Data When the App Opens

useEffect(() => {

  fetchStudents();

}, []);

Whenever the application screen initially opens, the student list is retrieved from the backend.

Step 5: Create an Add Student Function

Now create a function to insert a student record into MySQL.

const addStudent = async () => {

  if (
    !name.trim() ||
    !email.trim() ||
    !course.trim()
  ) {

    Alert.alert(
      "Validation",
      "Please fill all fields"
    );

    return;

  }

  try {

    const response = await fetch(API_URL, {

      method: "POST",

      headers: {
        "Content-Type": "application/json",
        "Accept": "application/json",
      },

      body: JSON.stringify({

        name: name.trim(),

        email: email.trim(),

        course: course.trim(),

      }),

    });

    const result = await response.json();

    if (!response.ok || !result.success) {

      throw new Error(
        result.message || "Unable to add student"
      );

    }

    Alert.alert(
      "Success",
      result.message
    );

    setName("");
    setEmail("");
    setCourse("");

    await fetchStudents();

  } catch (error) {

    Alert.alert("Error", error.message);

  }

};

Explanation:

  • method: "POST" tells PHP to insert a record.

  • Content-Type identifies the request body as JSON.

  • JSON.stringify() converts the JavaScript object into JSON.

  • PHP receives the information and inserts it into MySQL.

  • The student list refreshes after a successful operation.

Step 6: Create an Update Student Function

When the user selects an existing student, we will load that student's details into the input fields.

Then we can update the record using PUT.

const updateStudent = async () => {

  if (
    !name.trim() ||
    !email.trim() ||
    !course.trim()
  ) {

    Alert.alert(
      "Validation",
      "Please fill all fields"
    );

    return;

  }

  try {

    const response = await fetch(API_URL, {

      method: "PUT",

      headers: {
        "Content-Type": "application/json",
        "Accept": "application/json",
      },

      body: JSON.stringify({

        id: editingId,

        name: name.trim(),

        email: email.trim(),

        course: course.trim(),

      }),

    });

    const result = await response.json();

    if (!response.ok || !result.success) {

      throw new Error(
        result.message || "Unable to update student"
      );

    }

    Alert.alert(
      "Success",
      result.message
    );

    setName("");
    setEmail("");
    setCourse("");
    setEditingId(null);

    await fetchStudents();

  } catch (error) {

    Alert.alert("Error", error.message);

  }

};

Step 7: Create an Edit Function

This function fills the form with existing student information.

const editStudent = (student) => {

  setEditingId(student.id);

  setName(student.name);

  setEmail(student.email);

  setCourse(student.course);

};

Now the user can change the existing details and save them.

Step 8: Create a Delete Function

Now we will delete a student record from MySQL.

const deleteStudent = async (id) => {

  try {

    const response = await fetch(API_URL, {

      method: "DELETE",

      headers: {
        "Content-Type": "application/json",
        "Accept": "application/json",
      },

      body: JSON.stringify({ id }),

    });

    const result = await response.json();

    if (!response.ok || !result.success) {

      throw new Error(
        result.message || "Unable to delete student"
      );

    }

    Alert.alert(
      "Success",
      result.message
    );

    await fetchStudents();

  } catch (error) {

    Alert.alert("Error", error.message);

  }

};

This sends the student ID to PHP.

PHP executes the DELETE query, and MySQL removes the selected record.

Step 9: Create a Cancel Edit Function

const cancelEdit = () => {

  setEditingId(null);

  setName("");
  setEmail("");
  setCourse("");

};

This clears the form when the user does not want to continue editing.

15. Complete React Native Application Code

Now replace your entire App.js file with the following code.

Important: Before running the application, configure the API URL for your emulator or physical phone.

import React, { useEffect, useState } from "react";

import {
  View,
  Text,
  TextInput,
  Pressable,
  FlatList,
  StyleSheet,
  Alert,
  ActivityIndicator,
} from "react-native";

const API_URL =
  "http://10.0.2.2/student_api/students.php";

export default function App() {

  const [students, setStudents] = useState([]);

  const [name, setName] = useState("");

  const [email, setEmail] = useState("");

  const [course, setCourse] = useState("");

  const [loading, setLoading] = useState(false);

  const [editingId, setEditingId] = useState(null);

  const fetchStudents = async () => {

    try {

      setLoading(true);

      const response = await fetch(API_URL);

      const result = await response.json();

      if (!response.ok || !result.success) {

        throw new Error(
          result.message || "Unable to load students"
        );

      }

      setStudents(result.data);

    } catch (error) {

      Alert.alert("Error", error.message);

    } finally {

      setLoading(false);

    }

  };

  useEffect(() => {

    fetchStudents();

  }, []);

  const addStudent = async () => {

    if (
      !name.trim() ||
      !email.trim() ||
      !course.trim()
    ) {

      Alert.alert(
        "Validation",
        "Please fill all fields"
      );

      return;

    }

    try {

      const response = await fetch(API_URL, {

        method: "POST",

        headers: {
          "Content-Type": "application/json",
          "Accept": "application/json",
        },

        body: JSON.stringify({

          name: name.trim(),

          email: email.trim(),

          course: course.trim(),

        }),

      });

      const result = await response.json();

      if (!response.ok || !result.success) {

        throw new Error(
          result.message || "Unable to add student"
        );

      }

      Alert.alert("Success", result.message);

      setName("");
      setEmail("");
      setCourse("");

      await fetchStudents();

    } catch (error) {

      Alert.alert("Error", error.message);

    }

  };

  const editStudent = (student) => {

    setEditingId(student.id);

    setName(student.name);

    setEmail(student.email);

    setCourse(student.course);

  };

  const updateStudent = async () => {

    if (
      !name.trim() ||
      !email.trim() ||
      !course.trim()
    ) {

      Alert.alert(
        "Validation",
        "Please fill all fields"
      );

      return;

    }

    try {

      const response = await fetch(API_URL, {

        method: "PUT",

        headers: {
          "Content-Type": "application/json",
          "Accept": "application/json",
        },

        body: JSON.stringify({

          id: editingId,

          name: name.trim(),

          email: email.trim(),

          course: course.trim(),

        }),

      });

      const result = await response.json();

      if (!response.ok || !result.success) {

        throw new Error(
          result.message || "Unable to update student"
        );

      }

      Alert.alert("Success", result.message);

      setEditingId(null);

      setName("");
      setEmail("");
      setCourse("");

      await fetchStudents();

    } catch (error) {

      Alert.alert("Error", error.message);

    }

  };

  const deleteStudent = async (id) => {

    try {

      const response = await fetch(API_URL, {

        method: "DELETE",

        headers: {
          "Content-Type": "application/json",
          "Accept": "application/json",
        },

        body: JSON.stringify({ id }),

      });

      const result = await response.json();

      if (!response.ok || !result.success) {

        throw new Error(
          result.message || "Unable to delete student"
        );

      }

      Alert.alert("Success", result.message);

      await fetchStudents();

    } catch (error) {

      Alert.alert("Error", error.message);

    }

  };

  const cancelEdit = () => {

    setEditingId(null);

    setName("");
    setEmail("");
    setCourse("");

  };

  return (

    <View style={styles.container}>

      <Text style={styles.heading}>
        Student Management
      </Text>

      <Text style={styles.subtitle}>
        React Native + PHP + MySQL
      </Text>

      <TextInput
        style={styles.input}
        placeholder="Enter student name"
        value={name}
        onChangeText={setName}
      />

      <TextInput
        style={styles.input}
        placeholder="Enter student email"
        value={email}
        onChangeText={setEmail}
        keyboardType="email-address"
        autoCapitalize="none"
      />

      <TextInput
        style={styles.input}
        placeholder="Enter course"
        value={course}
        onChangeText={setCourse}
      />

      <Pressable
        style={styles.saveButton}
        onPress={
          editingId !== null
            ? updateStudent
            : addStudent
        }
      >

        <Text style={styles.buttonText}>

          {editingId !== null
            ? "Update Student"
            : "Add Student"}

        </Text>

      </Pressable>

      {editingId !== null && (

        <Pressable
          style={styles.cancelButton}
          onPress={cancelEdit}
        >

          <Text style={styles.buttonText}>
            Cancel Edit
          </Text>

        </Pressable>

      )}

      <Text style={styles.listHeading}>
        Student Records ({students.length})
      </Text>

      {loading ? (

        <ActivityIndicator
          size="large"
          color="#2563EB"
        />

      ) : (

        <FlatList

          data={students}

          keyExtractor={(item) =>
            item.id.toString()
          }

          refreshing={loading}

          onRefresh={fetchStudents}

          renderItem={({ item }) => (

            <View style={styles.card}>

              <Text style={styles.name}>
                {item.name}
              </Text>

              <Text style={styles.info}>
                ID: {item.id}
              </Text>

              <Text style={styles.info}>
                Email: {item.email}
              </Text>

              <Text style={styles.info}>
                Course: {item.course}
              </Text>

              <View style={styles.actions}>

                <Pressable
                  style={styles.editButton}
                  onPress={() => editStudent(item)}
                >

                  <Text style={styles.buttonText}>
                    Edit
                  </Text>

                </Pressable>

                <Pressable
                  style={styles.deleteButton}
                  onPress={() => deleteStudent(item.id)}
                >

                  <Text style={styles.buttonText}>
                    Delete
                  </Text>

                </Pressable>

              </View>

            </View>

          )}

          ListEmptyComponent={

            <Text style={styles.empty}>
              No student records found.
            </Text>

          }

        />

      )}

    </View>

  );

}

const styles = StyleSheet.create({

  container: {
    flex: 1,
    backgroundColor: "#F1F5F9",
    padding: 20,
    paddingTop: 55,
  },

  heading: {
    fontSize: 24,
    fontWeight: "bold",
    color: "#1E293B",
  },

  subtitle: {
    fontSize: 13,
    color: "#64748B",
    marginBottom: 20,
  },

  input: {
    backgroundColor: "#FFFFFF",
    padding: 13,
    borderRadius: 10,
    marginBottom: 10,
    borderWidth: 1,
    borderColor: "#CBD5E1",
  },

  saveButton: {
    backgroundColor: "#2563EB",
    padding: 14,
    borderRadius: 10,
    alignItems: "center",
    marginBottom: 10,
  },

  cancelButton: {
    backgroundColor: "#64748B",
    padding: 12,
    borderRadius: 10,
    alignItems: "center",
    marginBottom: 10,
  },

  buttonText: {
    color: "#FFFFFF",
    fontWeight: "bold",
  },

  listHeading: {
    fontSize: 19,
    fontWeight: "bold",
    color: "#1E293B",
    marginTop: 12,
    marginBottom: 12,
  },

  card: {
    backgroundColor: "#FFFFFF",
    padding: 15,
    borderRadius: 12,
    marginBottom: 12,
    elevation: 3,
  },

  name: {
    fontSize: 18,
    fontWeight: "bold",
    color: "#2563EB",
    marginBottom: 8,
  },

  info: {
    fontSize: 14,
    color: "#475569",
    marginBottom: 5,
  },

  actions: {
    flexDirection: "row",
    gap: 10,
    marginTop: 12,
  },

  editButton: {
    flex: 1,
    backgroundColor: "#0D9488",
    padding: 11,
    borderRadius: 8,
    alignItems: "center",
  },

  deleteButton: {
    flex: 1,
    backgroundColor: "#DC2626",
    padding: 11,
    borderRadius: 8,
    alignItems: "center",
  },

  empty: {
    textAlign: "center",
    color: "#64748B",
    marginTop: 20,
  },

});

16. Test the Complete Application

Now we will test the complete React Native + PHP + MySQL connection.

Keep Apache and MySQL running in XAMPP.

Start your React Native application.

Test 1: Retrieve Student Records

Open the mobile application.

The application should retrieve the existing records from MySQL.

You should see:

  • Rahul Sharma

  • Amit Kumar

Test 2: Add a Student

Enter:

Name: Priya Sharma

Email: priya@gmail.com

Course: PHP

Press Add Student.

Expected result:

  • React Native sends a POST request.

  • PHP receives the JSON data.

  • PHP validates the fields.

  • MySQL inserts a new record.

  • PHP returns a JSON response.

  • React Native refreshes the student list.

Test 3: Update a Student

Press Edit on Rahul Sharma's record.

Change the course to:

Advanced React Native

Press Update Student.

Expected result:

The existing MySQL record should be updated.

Test 4: Delete a Student

Press Delete on Amit Kumar's record.

Expected result:

The selected record should be removed from MySQL and disappear from the application.

Test 5: Verify MySQL Database

Open phpMyAdmin:

http://localhost/phpmyadmin/

Select:

student_api_db

Open the students table.

You should see the changes made through the mobile application.

This confirms that React Native is successfully communicating with PHP and MySQL.

17. Understand the Complete CRUD Workflow

Operation React Native PHP MySQL
Create POST INSERT Adds record
Read GET SELECT Retrieves records
Update PUT UPDATE Changes record
Delete DELETE DELETE Removes record

This is the foundation of many real-world mobile applications.

18. Common Errors and Solutions

Error 1: Network Request Failed

Possible reasons:

  • Incorrect API URL.

  • Apache is not running.

  • Phone and computer are on different networks.

  • Firewall is blocking the connection.

  • Incorrect emulator host address.

Solution:

For Android Studio emulator, verify:

http://10.0.2.2/student_api/students.php

For a physical phone, use your computer's local network IP.

Error 2: Database Connection Failed

Possible reasons:

  • Incorrect database name.

  • Incorrect username.

  • Incorrect password.

  • MySQL is not running.

  • PDO MySQL extension is unavailable.

Solution:

Check your db.php configuration and XAMPP services.

Error 3: 404 Not Found

Reason:

The PHP API file or folder cannot be found at the requested URL.

Solution:

Check that the files are inside:

C:\xampp\htdocs\student_api\

And that the URL is correct.

Error 4: 500 Internal Server Error

Possible reasons:

  • PHP syntax error.

  • Incorrect SQL query.

  • Database connection problem.

  • Missing PHP extension.

Solution:

Check the Apache PHP error log and PHP syntax.

Error 5: JSON Parsing Error

Reason:

PHP may be returning an HTML error page or PHP warning instead of JSON.

Solution:

  • Check PHP error logs.

  • Ensure the API returns JSON.

  • Avoid displaying PHP warnings in production responses.

  • Verify the response using an API client.

Error 6: React Native Cannot Connect to Localhost

Reason:

The mobile emulator and your computer use different network addresses.

Solution:

Use 10.0.2.2 for the standard Android Studio emulator or your computer's LAN IP for a physical phone.

Error 7: HTTP Cleartext Traffic Not Permitted

Some Android configurations block unencrypted HTTP connections.

Solution:

For development, use a suitable local HTTPS setup or a development configuration that explicitly permits the required local HTTP connection. Do not disable transport security broadly in a production application.

19. Important Security Best Practices

When building a real application, remember:

  1. Use PDO prepared statements for database operations.

  2. Validate all data on the PHP server.

  3. Never trust only React Native form validation.

  4. Do not expose database credentials in mobile application code.

  5. Use HTTPS in production.

  6. Implement authentication and authorization for protected APIs.

  7. Hash user passwords using PHP's password_hash().

  8. Verify passwords using password_verify().

  9. Avoid returning database credentials or internal error details.

  10. Add rate limiting and appropriate request-size limits.

  11. Restrict CORS origins if your API also serves web applications.

  12. Do not assume that hiding a button or screen provides security.

20. Practical Exercises

Complete these exercises to improve your understanding:

  1. Create a MySQL database named college_db.

  2. Create a table named students.

  3. Connect PHP to MySQL using PDO.

  4. Create a GET API to retrieve student records.

  5. Create a POST API to insert students.

  6. Create a PUT API to update student information.

  7. Create a DELETE API to remove student records.

  8. Connect the PHP API to React Native.

  9. Display student records using FlatList.

  10. Add a student using a mobile form.

  11. Edit an existing student.

  12. Delete a student and verify the database.

21. Conclusion

In this tutorial, we learned how to connect a React Native application to a PHP and MySQL backend.

We covered:

  • XAMPP configuration.

  • MySQL database creation.

  • Students table creation.

  • PHP database connection using PDO.

  • REST API development.

  • JSON request and response handling.

  • GET, POST, PUT and DELETE methods.

  • React Native Fetch API integration.

  • Android emulator networking.

  • Complete CRUD operations.

  • API error handling.

  • Backend security practices.

We also built a practical Student Management System that can add, view, update and delete student records from a React Native mobile application.

This architecture is widely used in real-world applications where mobile clients communicate with PHP backend services and MySQL databases.

22. Frequently Asked Questions

Q1. Can React Native connect to MySQL directly?

React Native should communicate with a backend API. PHP connects to MySQL and returns the required data to the application.

Q2. Why do we use PHP between React Native and MySQL?

PHP handles server-side business logic, validation, authentication and database operations.

Q3. What is a REST API?

A REST API allows applications to communicate using HTTP methods such as GET, POST, PUT and DELETE.

Q4. What is PDO in PHP?

PDO stands for PHP Data Objects. It provides a consistent interface for connecting PHP to supported databases.

Q5. What is JSON?

JSON is a lightweight data format commonly used to transfer information between React Native and PHP.

Q6. Why do we use 10.0.2.2?

The Android Studio emulator uses 10.0.2.2 as a special address to access the host computer's localhost.

Q7. Can we use Axios instead of Fetch?

Yes. Axios can send GET, POST, PUT and DELETE requests to the PHP API.

Q8. Can PHP update MySQL records?

Yes. PHP can execute SQL UPDATE queries through PDO or MySQLi.

Q9. Is XAMPP required for production?

No. XAMPP is useful for local development. A production application should use an appropriately configured server or hosting environment.

Q10. Can the same PHP API connect to Android and iOS applications?

Yes. Both Android and iOS applications can communicate with the same properly configured REST API.

←
Post 24 of 39
→