Lesson 146 of 158 – Project Search Student API
92%

Project Search Student API

In this lesson, we will create the Search Student API for our Student Management mobile application.

The React Native application will send a search keyword to the PHP REST API. The PHP API will search the MySQL database using a prepared statement and return matching students as JSON.

Project Goal: Build a secure student search API using PHP, MySQL, PDO, REST API, JWT authentication, Axios, and TypeScript.

1. Student Search API Flow

React Native Search Box
        ↓
Search Keyword
        ↓
Axios GET Request
        ↓
students.php?search=rahul
        ↓
JWT Verification
        ↓
PHP Search Logic
        ↓
MySQL LIKE Query
        ↓
JSON Response
        ↓
React Native FlatList

2. Search API URL

The search keyword can be sent using a query parameter.

GET /api/students.php?search=rahul

Here, search contains the keyword entered by the user.

3. Query Parameter

A query parameter is a value added after the question mark in a URL.

?search=rahul

Multiple query parameters can also be used.

?search=rahul&page=1&limit=10

4. Read Search Keyword in PHP

$search = trim(
    $_GET['search'] ?? ''
);

The PHP API reads the search keyword from the URL.

5. Empty Search

The API can return all students when no search keyword is provided, depending on the endpoint design.

if ($search === '') {

    // Return all students

} else {

    // Search students

}

In our project, this allows the same endpoint to support both the student list and search functionality.

6. Search Multiple Student Fields

We can search more than one column.

SELECT *
FROM students
WHERE name LIKE ?
   OR email LIKE ?
   OR mobile LIKE ?
   OR course LIKE ?

This allows users to search using name, email, mobile number, or course.

7. SQL LIKE Operator

The SQL LIKE operator is commonly used for text searching.

WHERE name LIKE ?

The percentage symbol can be used to find a keyword anywhere inside the column value.

%rahul%

8. Search with PDO Prepared Statement

$keyword = "%{$search}%";

$stmt = $pdo->prepare(
    "SELECT *
     FROM students
     WHERE name LIKE ?
        OR email LIKE ?
        OR mobile LIKE ?
        OR course LIKE ?"
);

$stmt->execute([
    $keyword,
    $keyword,
    $keyword,
    $keyword
]);

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

9. Why Prepared Statements Matter

Search input comes directly from the user. It should never be concatenated into an SQL query.

// Avoid

$sql =
    "SELECT * FROM students
     WHERE name LIKE '%$search%'";

Instead, use placeholders and PDO prepared statements.

10. Fetch Search Results

students =
    $stmt->fetchAll(
        PDO::FETCH_ASSOC
    );

The matching database rows are converted into a PHP array.

11. JSON Search Response

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

The PHP API sends the search results as JSON.

12. Search Result Example

{
    "success": true,
    "data": [
        {
            "id": 5,
            "name": "Rahul Kumar",
            "email": "rahul@example.com",
            "mobile": "9876543211",
            "course": "React Native"
        }
    ]
}

13. JWT Authentication

Student data should not be exposed through an unprotected administrative API.

Authorization:
Bearer YOUR_JWT_TOKEN

The API should verify the JWT before returning protected student data.

14. Read Authorization Header

$headers = getallheaders();

$authorization =
    $headers['Authorization']
    ?? '';

The server retrieves the Authorization header sent by Axios.

15. Verify JWT Before Search

if (
    !preg_match(
        '/Bearer\s(\S+)/',
        $authorization,
        $matches
    )
) {

    http_response_code(401);

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

    exit;
}

$token = $matches[1];

After extracting the token, the API should verify it using the same JWT secret and algorithm used during login.

16. Complete PHP Search Logic

$search = trim(
    $_GET['search'] ?? ''
);

if ($search === '') {

    $stmt = $pdo->prepare(
        "SELECT id, name, email,
                mobile, course, address
         FROM students
         ORDER BY id DESC"
    );

    $stmt->execute();

} else {

    $keyword = "%{$search}%";

    $stmt = $pdo->prepare(
        "SELECT id, name, email,
                mobile, course, address
         FROM students
         WHERE name LIKE ?
            OR email LIKE ?
            OR mobile LIKE ?
            OR course LIKE ?
         ORDER BY id DESC"
    );

    $stmt->execute([
        $keyword,
        $keyword,
        $keyword,
        $keyword
    ]);
}

$students = $stmt->fetchAll(
    PDO::FETCH_ASSOC
);

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

17. Complete Search Endpoint Structure

<?php

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

require_once '../config/database.php';
require_once __DIR__ .
    '/vendor/autoload.php';

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$secretKey =
    'CHANGE_THIS_TO_A_LONG_RANDOM_SECRET';

if ($_SERVER['REQUEST_METHOD'] !== 'GET') {

    http_response_code(405);

    echo json_encode([
        "success" => false,
        "message" => "Method not allowed"
    ]);

    exit;
}

$headers = getallheaders();

$authorization =
    $headers['Authorization']
    ?? '';

if (
    !preg_match(
        '/Bearer\s(\S+)/',
        $authorization,
        $matches
    )
) {

    http_response_code(401);

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

    exit;
}

$token = $matches[1];

try {

    JWT::decode(
        $token,
        new Key(
            $secretKey,
            'HS256'
        )
    );

    $search = trim(
        $_GET['search'] ?? ''
    );

    if ($search === '') {

        $stmt = $pdo->prepare(
            "SELECT id, name, email,
                    mobile, course, address
             FROM students
             ORDER BY id DESC"
        );

        $stmt->execute();

    } else {

        $keyword = "%{$search}%";

        $stmt = $pdo->prepare(
            "SELECT id, name, email,
                    mobile, course, address
             FROM students
             WHERE name LIKE ?
                OR email LIKE ?
                OR mobile LIKE ?
                OR course LIKE ?
             ORDER BY id DESC"
        );

        $stmt->execute([
            $keyword,
            $keyword,
            $keyword,
            $keyword
        ]);
    }

    $students = $stmt->fetchAll(
        PDO::FETCH_ASSOC
    );

    http_response_code(200);

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

} catch (Exception $e) {

    error_log($e->getMessage());

    http_response_code(401);

    echo json_encode([
        "success" => false,
        "message" =>
            "Invalid or expired token"
    ]);
}

18. React Native Search Input

The Student List screen can contain a TextInput for entering the search keyword.

<TextInput
    placeholder="Search student..."
    value={search}
    onChangeText={setSearch}
/>

Whenever the search value changes, the application can request matching students from the API.

19. TypeScript Search Function

const searchStudents =
    async (keyword: string) => {

    try {

        const response =
            await api.get(
                "/students.php",
                {
                    params: {
                        search: keyword
                    }
                }
            );

        setStudents(
            response.data.data
        );

    } catch (error) {

        console.log(
            "Search failed"
        );
    }
};

20. Axios Query Parameters

Axios provides a convenient params option for query parameters.

api.get(
    "/students.php",
    {
        params: {
            search: "rahul"
        }
    }
);

Axios converts this into a URL similar to:

/students.php?search=rahul

21. TypeScript Student Interface

interface Student {
    id: number;
    name: string;
    email: string;
    mobile: string;
    course: string;
    address: string;
}

This interface represents one student returned by the API.

22. Typed Search Response

interface StudentResponse {
    success: boolean;
    data: Student[];
}

We can use this interface to type the Axios response.

const response =
    await api.get<StudentResponse>(
        "/students.php",
        {
            params: {
                search: keyword
            }
        }
    );

23. Display Search Results with FlatList

<FlatList
    data={students}
    keyExtractor={item =>
        item.id.toString()
    }
    renderItem={({ item }) => (
        <View>
            <Text>
                {item.name}
            </Text>

            <Text>
                {item.course}
            </Text>

            <Text>
                {item.mobile}
            </Text>
        </View>
    )}
/>

FlatList is suitable for displaying a list of student records.

24. Search Loading and Empty State

{loading && (
    <ActivityIndicator />
)}

{!loading &&
 students.length === 0 && (
    <Text>
        No students found
    </Text>
)}

Loading and empty states provide better feedback to the user.

25. Search with Pagination

Large student databases should not return thousands of records in a single request.

/students.php
    ?search=rahul
    &page=1
    &limit=10

The API can combine search with pagination.

The previous project lesson on pagination can be used to calculate the SQL offset and return pagination metadata.

26. Search Testing in Postman

Method: GET

URL:

https://example.com/api/students.php?search=rahul

Header:

Authorization: Bearer YOUR_JWT_TOKEN

Example Response:

{
    "success": true,
    "data": [
        {
            "id": 5,
            "name": "Rahul Kumar",
            "email": "rahul@example.com",
            "mobile": "9876543211",
            "course": "React Native",
            "address": "Patna"
        }
    ]
}

27. Search Security

  • Always validate search input.
  • Use PDO prepared statements.
  • Do not concatenate search input into SQL.
  • Protect private student data with authentication.
  • Use HTTPS in production.
  • Do not return passwords or password hashes.
  • Return only fields required by the mobile application.
  • Use pagination for large datasets.

28. Search Performance

Searching with LIKE '%keyword%' is convenient, but large databases may require additional optimization.

Useful techniques include:

  • Limit the number of returned records.
  • Use pagination.
  • Search only required columns.
  • Use appropriate indexes where suitable.
  • Avoid loading the complete database into the mobile application.
  • Use server-side search instead of downloading all students.

29. Complete Mobile Search Flow

Student List Screen
        ↓
Search TextInput
        ↓
Search Keyword
        ↓
Axios GET
        ↓
JWT Authorization
        ↓
PHP Search API
        ↓
Validate Request
        ↓
PDO Prepared Statement
        ↓
MySQL LIKE Search
        ↓
JSON Response
        ↓
TypeScript Student[]
        ↓
FlatList
        ↓
Display Results

30. Search Student API Summary

The Search Student API allows the React Native application to find students without downloading the complete database.

  • The GET method is used for searching.
  • The search keyword is sent as a query parameter.
  • PHP reads the keyword using $_GET.
  • MySQL LIKE can perform partial matching.
  • PDO prepared statements help prevent SQL injection.
  • The API can search name, email, mobile, and course.
  • JWT authentication protects student information.
  • Axios sends the search request from React Native.
  • TypeScript interfaces provide type safety.
  • FlatList displays the search results.
  • Pagination should be used for large datasets.
  • The next lesson will add pagination to the Student API.

📌 Key Points

  • Use GET for student searching.
  • Use a query parameter such as ?search=rahul.
  • Use SQL LIKE for partial text matching.
  • Use PDO prepared statements.
  • Never concatenate user input directly into SQL.
  • Protect private student data using JWT authentication.
  • Axios can send query parameters using the params option.
  • TypeScript interfaces describe API response data.
  • FlatList is useful for displaying search results.
  • Pagination improves performance for large student databases.

🧠 Quick Quiz

Question: Which SQL operator is commonly used for partial text searching?