Lesson 66 of 158 – User Registration API
66%

User Registration API

A user registration API allows a mobile application to send new user information to a server and save it in a MySQL database. In this lesson, we will create a PHP REST API for registering users using JSON, PDO, validation, prepared statements, and proper API responses.

Note: Never store user passwords as plain text. Passwords should be securely hashed before they are stored in the database.

1. What is User Registration?

User registration is the process of creating a new user account in an application.

Mobile App
    ↓
Registration Form
    ↓
PHP REST API
    ↓
Validation
    ↓
MySQL Database
    ↓
Registration Response

2. Registration API Flow

A typical registration request follows this flow:

  1. User enters registration details.
  2. React Native creates a JSON request.
  3. PHP API receives the JSON data.
  4. PHP validates the input.
  5. Password is securely hashed.
  6. User is inserted into MySQL.
  7. API returns a JSON response.

3. User Table Structure

For this example, we can use a users table with fields such as:

users

id
name
email
mobile
password
created_at

The exact table structure can be adjusted according to your project.

4. Registration Endpoint

A registration API can use a POST endpoint.

POST /api/register.php

POST is appropriate because the API is creating a new user resource.

5. Set JSON Content Type

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

This tells the client that the API response is returned in JSON format.

6. Create PDO Connection

$pdo = new PDO(
    "mysql:host=localhost;dbname=schooldb",
    "root",
    ""
);

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

PDO provides a convenient and secure way to communicate with MySQL.

7. Read JSON Request

JSON data sent by a mobile application can be read using php://input.

$input = file_get_contents(
    "php://input"
);

$data = json_decode(
    $input,
    true
);

8. Example Registration JSON

The React Native application can send data such as:

{
    "name": "Rahul Kumar",
    "email": "rahul@example.com",
    "mobile": "9876543210",
    "password": "MyPassword123"
}

9. Check JSON Format

$input = file_get_contents(
    "php://input"
);

$data = json_decode(
    $input,
    true
);

if (json_last_error() !== JSON_ERROR_NONE) {

    http_response_code(400);

    echo json_encode([
        "success" => false,
        "message" => "Invalid JSON data"
    ]);

    exit;
}

Invalid JSON should be rejected before processing the registration.

10. Get Registration Fields

$name = trim(
    $data['name'] ?? ''
);

$email = trim(
    $data['email'] ?? ''
);

$mobile = trim(
    $data['mobile'] ?? ''
);

$password = $data['password'] ?? '';

Using the null coalescing operator helps prevent undefined array key warnings when a field is missing.

11. Validate Required Fields

if (
    $name === '' ||
    $email === '' ||
    $mobile === '' ||
    $password === ''
) {

    http_response_code(400);

    echo json_encode([
        "success" => false,
        "message" => "All fields are required"
    ]);

    exit;
}

12. Validate Email

PHP provides filter_var() for email validation.

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

    http_response_code(422);

    echo json_encode([
        "success" => false,
        "message" => "Invalid email address"
    ]);

    exit;
}

13. Validate Mobile Number

A simple validation can check whether the mobile number contains the expected number of digits.

if (!preg_match(
    '/^[0-9]{10}$/',
    $mobile
)) {

    http_response_code(422);

    echo json_encode([
        "success" => false,
        "message" => "Invalid mobile number"
    ]);

    exit;
}

14. Validate Password

You can enforce a minimum password length before creating an account.

if (strlen($password) < 6) {

    http_response_code(422);

    echo json_encode([
        "success" => false,
        "message" =>
            "Password must be at least 6 characters"
    ]);

    exit;
}

For production applications, stronger password rules can be added.

15. Check Existing Email

Before inserting a user, check whether the email is already registered.

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

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

if ($stmt->fetch()) {

    http_response_code(409);

    echo json_encode([
        "success" => false,
        "message" => "Email already registered"
    ]);

    exit;
}

16. Why Check Duplicate Email?

An email is often used as a unique identifier for a user account. Allowing duplicate emails can create problems during login.

Registration Request
        ↓
Check Email
        ↓
Already Exists?
   ┌────┴────┐
  Yes       No
   ↓          ↓
409 Error   Continue
              ↓
           Create User

17. Password Hashing

Never store a user's password directly in the database. PHP provides password_hash() for securely hashing passwords.

$hashedPassword = password_hash(
    $password,
    PASSWORD_DEFAULT
);

18. Insert User into Database

$stmt = $pdo->prepare(
    "INSERT INTO users
    (name, email, mobile, password)
    VALUES (?, ?, ?, ?)"
);

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

Prepared statements should be used instead of directly inserting user input into SQL queries.

19. Get New User ID

After a successful INSERT, PDO can return the new record ID.

$userId = $pdo->lastInsertId();

This ID can be included in the registration response if required.

20. Registration Success Response

http_response_code(201);

echo json_encode([
    "success" => true,
    "message" => "Registration successful",
    "user_id" => $userId
]);

HTTP 201 is appropriate when a new user resource has been created.

21. Create an Error Function

A reusable error function keeps the registration API clean.

function sendError(
    int $status,
    string $message
) {

    http_response_code($status);

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

    exit;
}

22. Use the Error Function

if ($name === '') {

    sendError(
        400,
        "Name is required"
    );
}
if (!filter_var(
    $email,
    FILTER_VALIDATE_EMAIL
)) {

    sendError(
        422,
        "Invalid email address"
    );
}

The same function can handle different registration errors.

23. Handle Database Exceptions

try {

    $stmt = $pdo->prepare(
        "INSERT INTO users
        (name, email, mobile, password)
        VALUES (?, ?, ?, ?)"
    );

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

} catch (PDOException $e) {

    error_log(
        $e->getMessage()
    );

    sendError(
        500,
        "Registration failed"
    );
}

24. Registration API Flow

POST Request
     ↓
Read JSON
     ↓
Validate JSON
     ↓
Validate Fields
     ↓
Check Email
     ↓
Hash Password
     ↓
Insert User
     ↓
Return JSON Response

25. Test Registration with Postman

To test the registration API in Postman:

  1. Select POST.
  2. Enter the registration API URL.
  3. Open the Body tab.
  4. Select raw.
  5. Select JSON.
  6. Enter the registration data.
  7. Click Send.
{
    "name": "Rahul Kumar",
    "email": "rahul@example.com",
    "mobile": "9876543210",
    "password": "MyPassword123"
}

26. React Native Registration Request

React Native can send the registration data using fetch().

fetch("https://example.com/api/register.php", {

    method: "POST",

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

    body: JSON.stringify({
        name: "Rahul Kumar",
        email: "rahul@example.com",
        mobile: "9876543210",
        password: "MyPassword123"
    })

})
.then(response => response.json())
.then(data => {

    console.log(data);

});

27. Handle Registration Response

fetch(url, options)
.then(async response => {

    const data =
        await response.json();

    if (!response.ok) {

        throw new Error(
            data.message
        );
    }

    return data;

})
.then(data => {

    console.log(
        "Registration successful"
    );

})
.catch(error => {

    console.log(
        error.message
    );

});

28. Complete Registration API

<?php

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

function sendError(
    int $status,
    string $message
) {

    http_response_code($status);

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

    exit;
}

try {

    $pdo = new PDO(
        "mysql:host=localhost;dbname=schooldb",
        "root",
        ""
    );

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

    $input = file_get_contents(
        "php://input"
    );

    $data = json_decode(
        $input,
        true
    );

    if (json_last_error() !== JSON_ERROR_NONE) {
        sendError(400, "Invalid JSON data");
    }

    $name = trim(
        $data['name'] ?? ''
    );

    $email = trim(
        $data['email'] ?? ''
    );

    $mobile = trim(
        $data['mobile'] ?? ''
    );

    $password =
        $data['password'] ?? '';

    if (
        $name === '' ||
        $email === '' ||
        $mobile === '' ||
        $password === ''
    ) {
        sendError(
            400,
            "All fields are required"
        );
    }

    if (!filter_var(
        $email,
        FILTER_VALIDATE_EMAIL
    )) {
        sendError(
            422,
            "Invalid email address"
        );
    }

    if (!preg_match(
        '/^[0-9]{10}$/',
        $mobile
    )) {
        sendError(
            422,
            "Invalid mobile number"
        );
    }

    if (strlen($password) < 6) {
        sendError(
            422,
            "Password must be at least 6 characters"
        );
    }

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

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

    if ($stmt->fetch()) {
        sendError(
            409,
            "Email already registered"
        );
    }

    $hashedPassword = password_hash(
        $password,
        PASSWORD_DEFAULT
    );

    $stmt = $pdo->prepare(
        "INSERT INTO users
        (name, email, mobile, password)
        VALUES (?, ?, ?, ?)"
    );

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

    $userId = $pdo->lastInsertId();

    http_response_code(201);

    echo json_encode([
        "success" => true,
        "message" => "Registration successful",
        "user_id" => $userId
    ]);

} catch (PDOException $e) {

    error_log(
        $e->getMessage()
    );

    sendError(
        500,
        "Registration failed"
    );
}

?>

29. Registration API Best Practices

  • Use POST for registration.
  • Accept registration data in JSON format.
  • Validate all required fields.
  • Validate email addresses.
  • Validate mobile numbers according to your application's requirements.
  • Use a minimum password length.
  • Always hash passwords before storing them.
  • Never store plain-text passwords.
  • Check for duplicate accounts.
  • Use prepared statements.
  • Return suitable HTTP status codes.
  • Return consistent JSON responses.
  • Do not expose database errors.
  • Use HTTPS when transmitting registration credentials.

30. Registration API Summary

A registration API connects the mobile registration form with the backend database. The client sends JSON using POST, PHP validates the information, checks for duplicate users, securely hashes the password, stores the user with a prepared statement, and returns a JSON response.

React Native
     ↓
POST JSON
     ↓
PHP Registration API
     ↓
Validate Data
     ↓
Check Duplicate
     ↓
Hash Password
     ↓
PDO + MySQL
     ↓
201 Created
     ↓
JSON Response

📌 Key Points

  • User registration creates a new account in the database.
  • Registration APIs normally use the POST method.
  • JSON can be received using php://input.
  • json_decode() converts JSON into PHP data.
  • All required registration fields should be validated.
  • filter_var() can be used for email validation.
  • Passwords must never be stored as plain text.
  • password_hash() can securely hash passwords.
  • Prepared statements should be used for database queries.
  • Duplicate emails should be handled before registration.
  • HTTP 409 can indicate an already registered email.
  • HTTP 422 can indicate invalid input.
  • HTTP 201 can indicate successful user creation.
  • PDOException can be handled using try-catch.
  • Technical database errors should be logged, not exposed to users.
  • React Native can send registration data using fetch().
  • The registration API should return a clear JSON response.

🧠 Quick Quiz

Question: Which PHP function should be used to securely hash a user's password before storing it in the database?