Flutter PHP

Sending Data From Flutter To MySql Database Using PHP

In this article we will do three major tasks:

  1. Create Sql Table
  2. Create the flutter checkout screen
  3. Create API using PHP

Step 1: Create SQL Table

CREATE TABLE checkout (
  id INT AUTO_INCREMENT PRIMARY KEY,
  c_name VARCHAR(255),
  c_mobile VARCHAR(10),
  c_state VARCHAR(255),
  c_address TEXT
);

The above SQL code creates a table called “checkout” with columns for storing customer information, including a unique identifier (id), name (c_name), mobile number (c_mobile), state (c_state), and address (c_address). The table is designed to efficiently store and retrieve customer checkout data for use in an application.

Step 2: Create a Flutter Screen Called Checkout

Certainly! Let’s break down the Flutter code for the Checkout Screen and explain it step by step for your blog post. This code handles form input and sends data to a server using HTTP POST requests.

Flutter Screen Part 1: Import Dependencies

import 'package:ecommerce_app/Home/Home.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

In this step, you import the necessary packages, including the Flutter framework, a custom Home widget, and the http package for making HTTP requests.

Flutter Screen Part 2: Create a Stateful Widget for CheckoutScreen

class CheckoutScreen extends StatefulWidget {
  const CheckoutScreen({Key? key}) : super(key: key);

  @override
  _CheckoutScreenState createState() => _CheckoutScreenState();
}

This step defines a stateful widget for the Checkout Screen. It extends StatefulWidget and specifies that it will use _CheckoutScreenState for its state.

Flutter Screen Part 3: Define State and Initialize Variables

class _CheckoutScreenState extends State<CheckoutScreen> {
  final _formKey = GlobalKey<FormState>();
  String selectedState = 'Select State';
  // Other variable declarations...
}

In this part, you create the state for the CheckoutScreen. You initialize a form key, a variable for the selected state, and other variables as needed for your form fields.

Flutter Screen Part 4: Build the Scaffold and UI

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text('Checkout Now'),
      backgroundColor: Colors.pink,
    ),
    body: SingleChildScrollView(
      child: Column(
        children: [
          // UI components such as images, headings, and the form...
        ],
      ),
    ),
  );
}

This step defines the UI of the Checkout Screen within a Scaffold. It includes an app bar, an image, a form, and other UI components.

Flutter Screen Part 5: Create Form Fields

Widget _buildTextInputField(
    String labelText, TextEditingController controller, {
    TextInputType inputType = TextInputType.text,
    String? Function(String?)? validator,
}) {
  return TextFormField(
    controller: controller,
    decoration: InputDecoration(
      labelText: labelText,
      border: OutlineInputBorder(
        borderRadius: BorderRadius.circular(50),
        borderSide: BorderSide(color: Colors.pink),
      ),
    ),
    keyboardType: inputType,
    validator: validator,
  );
}

This part defines a function _buildTextInputField to create text input fields for the form. It allows customization of input type and validation.

Flutter Screen Part 6: Create the State Dropdown

Widget _buildStateDropdown() {
  return DropdownButtonFormField<String>(
    // Dropdown UI...
  );
}

This function creates a state dropdown field. It uses DropdownButtonFormField and builds a dropdown list of Indian states.

Flutter Screen Part 7: Handle Form Submission

void sendDataToServer() async {
  // Create a map of the form data...
  // Make an HTTP POST request to send the form data...
}

This function, sendDataToServer, is called when the user submits the form. It creates a map of form data and sends it to the server via an HTTP POST request using the http package. The response is handled based on its status code.

Flutter Screen Part 8: Handle Response and Navigation

if (response.statusCode == 200) {
  // Request was successful, you can handle the response here...
} else {
  // Request failed, handle the error...
}

In this part, you check the response status code. If the request is successful (status code 200), you can handle the response. If there’s an error, you handle it accordingly. In this example, if the request is successful, it navigates to the “Home” screen using Navigator.

Flutter Screen Final: Full Source Code

import 'package:ecommerce_app/Home/Home.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http; // Import the http package.

class CheckoutScreen extends StatefulWidget {
  const CheckoutScreen({Key? key}) : super(key: key);

  @override
  _CheckoutScreenState createState() => _CheckoutScreenState();
}

class _CheckoutScreenState extends State<CheckoutScreen> {
  final _formKey = GlobalKey<FormState>();
  String selectedState = 'Select State';

  List<String> indianStates = [
    'Select State',
    'Andhra Pradesh',
    'Arunachal Pradesh',
    'Assam',
    'Bihar',
    'Chhattisgarh',
    'Goa',
    'Gujarat',
    'Haryana',
    'Himachal Pradesh',
    'Jharkhand',
    'Karnataka',
    'Kerala',
    'Madhya Pradesh',
    'Maharashtra',
    'Manipur',
    'Meghalaya',
    'Mizoram',
    'Nagaland',
    'Odisha',
    'Punjab',
    'Rajasthan',
    'Sikkim',
    'Tamil Nadu',
    'Telangana',
    'Tripura',
    'Uttar Pradesh',
    'Uttarakhand',
    'West Bengal',
    // Rest of the states
  ];

  // Define controllers for the form fields to get their values.
  TextEditingController nameController = TextEditingController();
  TextEditingController mobileController = TextEditingController();
  TextEditingController addressController = TextEditingController();

  @override
  void dispose() {
    nameController.dispose();
    mobileController.dispose();
    addressController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Checkout Now'),
        backgroundColor: Colors.pink,
      ),
      body: SingleChildScrollView(
        child: Column(
          children: [
            Container(
              margin: EdgeInsets.all(30),
              child: Image.network('https://booppers.tk/assets/img/cart.png'),
            ),
            SizedBox(height: 20),
            Container(
              margin: EdgeInsets.all(10),
              alignment: Alignment.center,
              child: Text('Checkout Now', style: TextStyle(fontSize: 25)),
            ),
            Form(
              key: _formKey,
              child: Column(
                children: <Widget>[
                  _buildTextInputField('Your Name', nameController),
                  SizedBox(height: 20),
                  _buildTextInputField('Your Mobile Number', mobileController,
                      inputType: TextInputType.number,
                      validator: (value) {
                        if (value!.isEmpty) {
                          return 'Please enter your mobile number';
                        } else if (value.length != 10) {
                          return 'Mobile number should be 10 digits';
                        }
                        return null;
                      }),
                  SizedBox(height: 20),
                  _buildStateDropdown(),
                  SizedBox(height: 20),
                  _buildTextInputField('Your Address', addressController),
                  ElevatedButton(
                    onPressed: () {
                      if (_formKey.currentState!.validate()) {
                        // Form is valid, send data to the server.
                        sendDataToServer();
                      }
                    },
                    child: Text('Submit'),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildTextInputField(
      String labelText, TextEditingController controller, {
        TextInputType inputType = TextInputType.text,
        String? Function(String?)? validator,
      }) {
    return TextFormField(
      controller: controller,
      decoration: InputDecoration(
        labelText: labelText,
        border: OutlineInputBorder(
          borderRadius: BorderRadius.circular(50),
          borderSide: BorderSide(color: Colors.pink),
        ),
      ),
      keyboardType: inputType,
      validator: validator,
    );
  }

  Widget _buildStateDropdown() {
    return DropdownButtonFormField<String>(
      decoration: InputDecoration(
        labelText: 'Your State',
        border: OutlineInputBorder(
          borderRadius: BorderRadius.circular(50),
          borderSide: BorderSide(color: Colors.pink),
        ),
      ),
      value: selectedState,
      items: indianStates.map((state) {
        return DropdownMenuItem<String>(
          value: state,
          child: Text(state),
        );
      }).toList(),
      onChanged: (value) {
        setState(() {
          selectedState = value!;
        });
      },
    );
  }

  void sendDataToServer() async {
    // Create a map of the form data.
    Map<String, String> formData = {
      'name': nameController.text,
      'mobile': mobileController.text,
      'state': selectedState,
      'address': addressController.text,
    };

    // Make an HTTP POST request to send the form data.
    final response = await http.post(
      Uri.parse('https://booppers.tk/api/checkout.php'),
      body: formData,
    );

    if (response.statusCode == 200) {
      // Request was successful, you can handle the response here.
      print('Response: ${response.body}');
      // Request was successful, navigate to the thank you page.
      Navigator.push(
        context,
        MaterialPageRoute(builder: (context) => Home()),
      );
    } else {
      // Request failed, handle the error.
      print('Error: ${response.reasonPhrase}');
    }
  }
}

Step 3: Create API Using PHP

Here’s the PHP code for handling a POST request and inserting data into a MySQL database:

PHP API Part 1: Import Necessary Files and Establish a Database Connection

<?php
// Include necessary files and establish a PDO database connection.
include('cors.php');      // Include CORS handling if needed.
include('../database.php'); // Include the database connection script.

In this step, you import any required files and establish a connection to your MySQL database using PDO. Replace 'cors.php' and '../database.php' with the actual file paths or include statements for your project. The database.php file should contain the database connection details.

PHP API Part 2: Set Response Content Type to JSON

// Set the response content type to JSON.
header('Content-Type: application/json');

This sets the HTTP response header to indicate that the response will be in JSON format.

PHP API Part 3: Initialize an Empty Response Array

// Initialize an empty response array to hold the result.
$response = array();

You create an empty associative array named $response to store the response data that will be sent back to the client.

PHP API Part 4: Check Request Method

// Check if the request is a POST request.
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // Handle the POST request here.
} else {
    // Handle other request methods (e.g., GET).
}

This part checks the HTTP request method. It specifically looks for POST requests. If the request method is POST, the code inside the if block will be executed.

PHP API Part 5: Retrieve Data from the POST Request

// Get data from the POST request.
$c_name = $_POST['name'];
$c_mobile = $_POST['mobile'];
$c_state = $_POST['state'];
$c_address = $_POST['address'];

Here, you retrieve data from the POST request. It assumes that the POST data includes fields named ‘name,’ ‘mobile,’ ‘state,’ and ‘address.’ These values will be used to insert data into the database.

This is where you retrieve the values sent by the Flutter application when a user submits the form.

PHP API Part 6: Create SQL Query and Prepared Statement

// Create an SQL query to insert the data into the database using prepared statements.
$sql = "INSERT INTO checkout (c_name, c_mobile, c_state, c_address) VALUES (:name, :mobile, :state, :address)";

// Prepare the SQL statement for execution.
$stmt = $conn->prepare($sql);

In this step, you define the SQL query that will insert data into your database table, “checkout.” You use prepared statements for security. The :name, :mobile, :state, and :address are placeholders for values that will be inserted later.

PHP API Part 7: Bind Parameters to Prepared Statement

// Bind the parameters to the prepared statement.
$stmt->bindParam(':name', $c_name);
$stmt->bindParam(':mobile', $c_mobile);
$stmt->bindParam(':state', $c_state);
$stmt->bindParam(':address', $c_address);

Here, you bind the values you retrieved from the POST request to the placeholders in the prepared statement. This process ensures that data is securely inserted into the database.

PHP API Part 8: Execute the Prepared Statement and Handle Success/Failure

// Execute the prepared statement.
if ($stmt->execute()) {
    // If data insertion is successful, set success to true and provide a success message.
    $response['success'] = true;
    $response['message'] = "Data inserted successfully.";
} else {
    // If an error occurs during data insertion, set success to false and provide an error message.
    $response['success'] = false;
    $response['message'] = "Error: " . $stmt->errorInfo();
}

In this step, you execute the prepared statement. If the insertion is successful, you set the success key in the response array to true and provide a success message. If an error occurs during data insertion, success is set to false, and you provide an error message. The errorInfo() method is used to fetch the error details.

PHP API Part 9: Handle Invalid Request Method

} else {
    // If the request method is not POST, set success to false and provide an error message for an invalid request method.
    $response['success'] = false;
    $response['message'] = "Invalid request method.";
}

This part of the code handles cases where the HTTP request method is not POST. In such cases, the success key is set to false, and an error message is provided, indicating that the request method is invalid.

PHP API Part 10: Output the Response as JSON

// Output the response as a JSON-encoded string.
echo json_encode($response);

Finally, you convert the response array into a JSON-encoded string and send it as the HTTP response to the Flutter client.

This code serves as the backend API for your Flutter application, allowing it to send checkout data to the server for storage in the MySQL database. It also handles errors and sends informative responses back to the client.

PHP API Full Source Code

<?php
include('cors.php');
include('../database.php');

// Assuming you have already established a PDO database connection in database.php
// Replace database credentials with your own.

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

// Initialize an empty response.
$response = array();

// Check if the request is a POST request.
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // Get data from the POST request.
    $c_name = $_POST['name'];
    $c_mobile = $_POST['mobile'];
    $c_state = $_POST['state'];
    $c_address = $_POST['address'];

    // Insert the data into the database using prepared statements.
    $sql = "INSERT INTO checkout (c_name, c_mobile, c_state, c_address) VALUES (:name, :mobile, :state, :address)";
    $stmt = $conn->prepare($sql);
    
    // Bind the parameters.
    $stmt->bindParam(':name', $c_name);
    $stmt->bindParam(':mobile', $c_mobile);
    $stmt->bindParam(':state', $c_state);
    $stmt->bindParam(':address', $c_address);

    if ($stmt->execute()) {
        $response['success'] = true;
        $response['message'] = "Data inserted successfully.";
    } else {
        $response['success'] = false;
        $response['message'] = "Error: " . $stmt->errorInfo();
    }
} else {
    $response['success'] = false;
    $response['message'] = "Invalid request method.";
}

// Output the response as JSON.
echo json_encode($response);
?>

Leave a Reply

Your email address will not be published. Required fields are marked *