Jinsi ya Kujifunza PHP Hatua kwa Hatua kwa Mfano wa Mfumo Kamili
PHP ni lugha inayotumika kutengeneza tovuti zinazoweza kupokea, kuhifadhi, kuhariri na kuonyesha taarifa kutoka kwenye database. Katika somo hili tutajifunza PHP kwa kutengeneza mfumo mdogo wa kusajili wanafunzi.
Vitu unavyohitaji
Kabla ya kuanza, hakikisha una:
- XAMPP au Laragon
- Code editor kama Visual Studio Code
- Browser kama Chrome
- Maarifa kidogo ya HTML
- Apache na MySQL vimewashwa
Hatua ya 1: Tengeneza project
Ndani ya folder la htdocs, tengeneza folder:
php_studentsNdani yake tengeneza faili:
index.phpProject itapatikana kupitia:
http://localhost/php_students/Hatua ya 2: Tengeneza database
Fungua phpMyAdmin kupitia:
http://localhost/phpmyadminChagua sehemu ya SQL, kisha tumia code hii:
CREATE DATABASE php_school
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
USE php_school;
CREATE TABLE students (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
student_name VARCHAR(150) NOT NULL,
gender ENUM('Male', 'Female') NOT NULL,
class_name VARCHAR(100) NOT NULL,
phone_number VARCHAR(20) DEFAULT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);Table hii itahifadhi:
- Namba ya mwanafunzi
- Jina
- Jinsia
- Darasa
- Namba ya simu
- Tarehe ya kusajiliwa
Hatua ya 3: Code kamili ya PHP
Weka code hii yote ndani ya index.php:
<?php
declare(strict_types=1);
session_start();
/*
|--------------------------------------------------------------------------
| DATABASE CONNECTION
|--------------------------------------------------------------------------
*/
$host = 'localhost';
$database = 'php_school';
$username = 'root';
$password = '';
try {
$pdo = new PDO(
"mysql:host={$host};dbname={$database};charset=utf8mb4",
$username,
$password,
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false
]
);
} catch (PDOException $e) {
exit('Imeshindikana kuunganisha database.');
}
/*
|--------------------------------------------------------------------------
| HELPER FUNCTION
|--------------------------------------------------------------------------
*/
function escape(string $value): string
{
return htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
}
/*
|--------------------------------------------------------------------------
| CSRF SECURITY
|--------------------------------------------------------------------------
*/
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
$csrfToken = $_SESSION['csrf_token'];
$error = '';
$success = '';
/*
|--------------------------------------------------------------------------
| DELETE STUDENT
|--------------------------------------------------------------------------
*/
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_student'])) {
$submittedToken = (string)($_POST['csrf_token'] ?? '');
if (!hash_equals($csrfToken, $submittedToken)) {
$error = 'Ombi limekataliwa kwa sababu za kiusalama.';
} else {
$studentId = (int)($_POST['student_id'] ?? 0);
if ($studentId > 0) {
$statement = $pdo->prepare(
'DELETE FROM students WHERE id = ?'
);
$statement->execute([$studentId]);
header('Location: index.php?message=deleted');
exit;
}
}
}
/*
|--------------------------------------------------------------------------
| ADD OR UPDATE STUDENT
|--------------------------------------------------------------------------
*/
if (
$_SERVER['REQUEST_METHOD'] === 'POST' &&
(isset($_POST['add_student']) || isset($_POST['update_student']))
) {
$submittedToken = (string)($_POST['csrf_token'] ?? '');
if (!hash_equals($csrfToken, $submittedToken)) {
$error = 'Ombi limekataliwa kwa sababu za kiusalama.';
} else {
$studentName = trim((string)($_POST['student_name'] ?? ''));
$gender = (string)($_POST['gender'] ?? '');
$className = trim((string)($_POST['class_name'] ?? ''));
$phoneNumber = trim((string)($_POST['phone_number'] ?? ''));
if ($studentName === '' || $gender === '' || $className === '') {
$error = 'Tafadhali jaza jina, jinsia na darasa.';
} elseif (!in_array($gender, ['Male', 'Female'], true)) {
$error = 'Jinsia iliyochaguliwa si sahihi.';
} else {
if (isset($_POST['add_student'])) {
$statement = $pdo->prepare(
'INSERT INTO students
(student_name, gender, class_name, phone_number)
VALUES (?, ?, ?, ?)'
);
$statement->execute([
$studentName,
$gender,
$className,
$phoneNumber !== '' ? $phoneNumber : null
]);
header('Location: index.php?message=added');
exit;
}
if (isset($_POST['update_student'])) {
$studentId = (int)($_POST['student_id'] ?? 0);
if ($studentId > 0) {
$statement = $pdo->prepare(
'UPDATE students
SET student_name = ?,
gender = ?,
class_name = ?,
phone_number = ?
WHERE id = ?'
);
$statement->execute([
$studentName,
$gender,
$className,
$phoneNumber !== '' ? $phoneNumber : null,
$studentId
]);
header('Location: index.php?message=updated');
exit;
}
}
}
}
}
/*
|--------------------------------------------------------------------------
| SUCCESS MESSAGE
|--------------------------------------------------------------------------
*/
$message = (string)($_GET['message'] ?? '');
if ($message === 'added') {
$success = 'Mwanafunzi amesajiliwa vizuri.';
} elseif ($message === 'updated') {
$success = 'Taarifa za mwanafunzi zimebadilishwa.';
} elseif ($message === 'deleted') {
$success = 'Mwanafunzi amefutwa.';
}
/*
|--------------------------------------------------------------------------
| EDIT MODE
|--------------------------------------------------------------------------
*/
$editStudent = null;
$editId = (int)($_GET['edit'] ?? 0);
if ($editId > 0) {
$statement = $pdo->prepare(
'SELECT * FROM students WHERE id = ? LIMIT 1'
);
$statement->execute([$editId]);
$editStudent = $statement->fetch() ?: null;
}
/*
|--------------------------------------------------------------------------
| SEARCH STUDENTS
|--------------------------------------------------------------------------
*/
$search = trim((string)($_GET['search'] ?? ''));
if ($search !== '') {
$statement = $pdo->prepare(
'SELECT *
FROM students
WHERE student_name LIKE ?
OR class_name LIKE ?
ORDER BY id DESC'
);
$searchValue = '%' . $search . '%';
$statement->execute([$searchValue, $searchValue]);
$students = $statement->fetchAll();
} else {
$statement = $pdo->query(
'SELECT * FROM students ORDER BY id DESC'
);
$students = $statement->fetchAll();
}
?>
<!DOCTYPE html>
<html lang="sw">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Mfumo wa Kusajili Wanafunzi</title>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
rel="stylesheet"
>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css"
rel="stylesheet"
>
<style>
body {
min-height: 100vh;
background: linear-gradient(135deg, #eff6ff, #f8fafc);
}
.navbar {
background: linear-gradient(135deg, #0f172a, #1d4ed8);
}
.page-card {
background: #ffffff;
border: 1px solid #e2e8f0;
border-radius: 20px;
box-shadow: 0 15px 40px rgba(15, 23, 42, 0.08);
}
.form-control,
.form-select {
min-height: 48px;
border-radius: 12px;
}
.btn {
border-radius: 12px;
font-weight: 700;
}
.table thead th {
background: #0f274f;
color: #ffffff;
white-space: nowrap;
}
.student-number {
display: inline-block;
min-width: 35px;
padding: 5px 9px;
text-align: center;
border-radius: 8px;
background: #eff6ff;
color: #1d4ed8;
font-weight: 800;
}
</style>
</head>
<body>
<nav class="navbar navbar-dark">
<div class="container">
<a class="navbar-brand fw-bold" href="index.php">
<i class="bi bi-mortarboard-fill me-2"></i>
Mfumo wa Wanafunzi
</a>
</div>
</nav>
<main class="container py-5">
<div class="mb-4">
<h1 class="fw-bold">Usajili wa Wanafunzi</h1>
<p class="text-muted">
Ongeza, hariri, tafuta na kufuta taarifa za wanafunzi.
</p>
</div>
<?php if ($error !== ''): ?>
<div class="alert alert-danger">
<?= escape($error) ?>
</div>
<?php endif; ?>
<?php if ($success !== ''): ?>
<div class="alert alert-success">
<?= escape($success) ?>
</div>
<?php endif; ?>
<div class="row g-4">
<div class="col-lg-4">
<section class="page-card p-4">
<h4 class="fw-bold mb-3">
<?php if ($editStudent): ?>
<i class="bi bi-pencil-square me-1"></i>
Hariri Mwanafunzi
<?php else: ?>
<i class="bi bi-person-plus me-1"></i>
Sajili Mwanafunzi
<?php endif; ?>
</h4>
<form method="post">
<input
type="hidden"
name="csrf_token"
value="<?= escape($csrfToken) ?>"
>
<?php if ($editStudent): ?>
<input
type="hidden"
name="student_id"
value="<?= (int)$editStudent['id'] ?>"
>
<?php endif; ?>
<div class="mb-3">
<label class="form-label fw-semibold">
Jina kamili
</label>
<input
type="text"
name="student_name"
class="form-control"
value="<?= escape($editStudent['student_name'] ?? '') ?>"
placeholder="Mfano: Asha Ally"
required
>
</div>
<div class="mb-3">
<label class="form-label fw-semibold">
Jinsia
</label>
<select name="gender" class="form-select" required>
<option value="">Chagua jinsia</option>
<option
value="Male"
<?= ($editStudent['gender'] ?? '') === 'Male'
? 'selected'
: '' ?>
>
Mvulana
</option>
<option
value="Female"
<?= ($editStudent['gender'] ?? '') === 'Female'
? 'selected'
: '' ?>
>
Msichana
</option>
</select>
</div>
<div class="mb-3">
<label class="form-label fw-semibold">
Darasa
</label>
<input
type="text"
name="class_name"
class="form-control"
value="<?= escape($editStudent['class_name'] ?? '') ?>"
placeholder="Mfano: Form One"
required
>
</div>
<div class="mb-3">
<label class="form-label fw-semibold">
Namba ya simu
</label>
<input
type="tel"
name="phone_number"
class="form-control"
value="<?= escape($editStudent['phone_number'] ?? '') ?>"
placeholder="Mfano: 0712345678"
>
</div>
<div class="d-grid gap-2">
<?php if ($editStudent): ?>
<button
type="submit"
name="update_student"
class="btn btn-warning"
>
<i class="bi bi-check-circle me-1"></i>
Hifadhi Mabadiliko
</button>
<a
href="index.php"
class="btn btn-outline-secondary"
>
Acha Kuhariri
</a>
<?php else: ?>
<button
type="submit"
name="add_student"
class="btn btn-primary"
>
<i class="bi bi-person-check me-1"></i>
Sajili Mwanafunzi
</button>
<?php endif; ?>
</div>
</form>
</section>
</div>
<div class="col-lg-8">
<section class="page-card overflow-hidden">
<div class="p-4 border-bottom">
<div class="d-flex flex-column flex-md-row gap-3
justify-content-between align-items-md-center">
<div>
<h4 class="fw-bold mb-1">
Orodha ya Wanafunzi
</h4>
<span class="text-muted">
Jumla: <?= count($students) ?>
</span>
</div>
<form method="get" class="d-flex gap-2">
<input
type="search"
name="search"
class="form-control"
value="<?= escape($search) ?>"
placeholder="Tafuta jina au darasa"
>
<button class="btn btn-primary">
<i class="bi bi-search"></i>
</button>
</form>
</div>
</div>
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead>
<tr>
<th>Namba</th>
<th>Jina</th>
<th>Jinsia</th>
<th>Darasa</th>
<th>Simu</th>
<th>Vitendo</th>
</tr>
</thead>
<tbody>
<?php if (!$students): ?>
<tr>
<td
colspan="6"
class="text-center text-muted py-5"
>
Hakuna mwanafunzi aliyepatikana.
</td>
</tr>
<?php endif; ?>
<?php foreach ($students as $index => $student): ?>
<tr>
<td>
<span class="student-number">
<?= $index + 1 ?>
</span>
</td>
<td class="fw-semibold">
<?= escape($student['student_name']) ?>
</td>
<td>
<?= escape($student['gender']) ?>
</td>
<td>
<?= escape($student['class_name']) ?>
</td>
<td>
<?= escape($student['phone_number'] ?? '-') ?>
</td>
<td class="text-nowrap">
<a
href="?edit=<?= (int)$student['id'] ?>"
class="btn btn-sm btn-warning"
>
<i class="bi bi-pencil"></i>
Hariri
</a>
<form
method="post"
class="d-inline"
onsubmit="return confirm(
'Una uhakika unataka kufuta mwanafunzi huyu?'
);"
>
<input
type="hidden"
name="csrf_token"
value="<?= escape($csrfToken) ?>"
>
<input
type="hidden"
name="student_id"
value="<?= (int)$student['id'] ?>"
>
<button
type="submit"
name="delete_student"
class="btn btn-sm btn-danger"
>
<i class="bi bi-trash"></i>
Futa
</button>
</form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</section>
</div>
</div>
</main>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>Hatua ya 4: Kuelewa sehemu muhimu za code
Kuunganisha database
$pdo = new PDO(
"mysql:host={$host};dbname={$database};charset=utf8mb4",
$username,
$password
);PDO inaunganisha PHP na MySQL. Pia inasaidia kutumia prepared statements ambazo ni salama zaidi.
Kupokea taarifa za form
$studentName = trim($_POST['student_name'] ?? '');$_POST inapokea taarifa zilizotumwa na form. trim() inaondoa nafasi zisizohitajika.
Kuingiza taarifa
$statement = $pdo->prepare(
'INSERT INTO students
(student_name, gender, class_name, phone_number)
VALUES (?, ?, ?, ?)'
);
$statement->execute([
$studentName,
$gender,
$className,
$phoneNumber
]);Prepared statement husaidia kuzuia SQL injection.
Kuonyesha taarifa
$statement = $pdo->query(
'SELECT * FROM students ORDER BY id DESC'
);
$students = $statement->fetchAll();SELECT inachukua taarifa kutoka MySQL. fetchAll() inaziweka kwenye array.
Kuhariri taarifa
UPDATE students
SET student_name = ?,
gender = ?,
class_name = ?,
phone_number = ?
WHERE id = ?UPDATE hubadilisha record iliyochaguliwa.
Kufuta taarifa
DELETE FROM students WHERE id = ?DELETE huondoa record kwenye database.
Kulinda output
htmlspecialchars($value, ENT_QUOTES, 'UTF-8');Hii inazuia HTML au JavaScript hatari kuingizwa na kuendeshwa kwenye ukurasa.
Hatua ya 5: Kuendesha mfumo
- Washa Apache na MySQL.
- Hakikisha database
php_schoolipo. - Hifadhi code kwenye
htdocs/php_students/index.php. - Fungua:
http://localhost/php_students/Sasa unaweza:
- Kusajili mwanafunzi
- Kuonyesha wanafunzi
- Kutafuta kwa jina au darasa
- Kuhariri taarifa
- Kufuta mwanafunzi
Hitimisho
Njia nzuri ya kujifunza PHP ni kutengeneza project halisi. Mfumo huu umeonyesha matumizi ya:
- Variables
- Arrays
- Conditions
- Forms
GETnaPOST- PHP sessions
- PDO
- MySQL
- CRUD
- Prepared statements
- CSRF protection
- Bootstrap
Baada ya kuelewa mfumo huu unaweza kuendelea kujifunza login system, user roles, pagination, upload ya Excel, reports na mfumo wa matokeo.
🚀 Unahitaji mfumo au website ya biashara?
Chagua huduma hapa chini kisha mteja bofya moja kwa moja kwenda kwenye ukurasa wa huduma au kuwasiliana nasi kwa WhatsApp.