Skip to content

Rejestr obecności

This content is not available in your language yet.

Stworzysz Rejestr obecności - aplikację do prowadzenia ewidencji obecności uczniów na zajęciach. System pozwala dodawać wpisy z datą i statusem, generować podsumowania i eksportować raporty.

Czego się nauczysz?

  • Pracy z datami i formatowaniem w PHP
  • Walidacji ograniczonego zestawu wartości (statusy)
  • Zliczania i agregowania danych
  • Generowania raportów i statystyk
  • Tworzenia podsumowań per osoba/dzień

W prawdziwej pracy...

Systemy ewidencji obecności są niezbędne w każdej organizacji - od szkół i uczelni, przez firmy, po wydarzenia i konferencje. Umiejętność projektowania systemów z walidacją statusów, agregacją danych i raportowaniem jest fundamentem dla każdego programisty aplikacji HR i administracyjnych.

  1. Formularz dodawania obecności Użytkownik wybiera datę, ucznia i status obecności (obecny, nieobecny, spóźniony).

  2. Walidacja danych System sprawdza poprawność wprowadzonych danych - czy status jest z dozwolonej listy, czy data jest prawidłowa.

  3. Lista obecności Wszystkie wpisy są wyświetlane w formie tabeli, posortowane chronologicznie.

  4. Podgląd szczegółów Użytkownik może zobaczyć szczegóły obecności konkretnego ucznia lub dnia.

Przykładowa struktura pliku JSON:

{
"attendance": [
{
"id": 1,
"date": "2026-02-10",
"student": "Jan Kowalski",
"student_id": "1A01",
"status": "present",
"notes": "",
"recorded_by": "Nauczyciel",
"created_at": "2026-02-10 08:15:00"
},
{
"id": 2,
"date": "2026-02-10",
"student": "Anna Nowak",
"student_id": "1A02",
"status": "late",
"notes": "Spóźnienie 10 min",
"recorded_by": "Nauczyciel",
"created_at": "2026-02-10 08:20:00"
},
{
"id": 3,
"date": "2026-02-10",
"student": "Piotr Wiśniewski",
"student_id": "1A03",
"status": "absent",
"notes": "Choroba - zwolnienie lekarskie",
"recorded_by": "Nauczyciel",
"created_at": "2026-02-10 08:00:00"
}
]
}
  • Directoryrejestr-obecnosci/
    • index.php (lista obecności)
    • dodaj.php (formularz dodawania)
    • podsumowanie.php (statystyki ucznia)
    • dzień.php (obecność w dniu)
    • raport.php (eksport raportu - wariant C)
    • Directoryincludes/
      • config.php
      • functions.php
      • validation.php
      • auth.php (wariant C)
    • Directorydata/
      • attendance.json
      • students.json
      • users.json (wariant C)
    • Directorycss/
      • style.css
    • Directoryjs/
      • validation.js

Wymagane funkcje:

  • Formularz dodawania: data, uczeń, status (select)
  • Walidacja PHP (status z dozwolonej listy)
  • Min. 1 walidacja JavaScript
  • Zapis obecności do pliku JSON
  • Lista wszystkich wpisów obecności
  • Komunikaty błędów i sukcesu

Przykładowy scenariusz:

Nauczyciel wchodzi na stronę i widzi formularz. Wybiera datę 10.02.2026, ucznia “Jan Kowalski” i status “obecny”. Po zapisie widzi wpis na liście z zielonym znacznikiem.

Ocena: 3.0

Walidacja statusu obecności:

$date = $_POST['date'] ?? '';
$student = trim($_POST['student'] ?? '');
$status = $_POST['status'] ?? '';
$validStatuses = ['present', 'absent', 'late', 'excused'];
if (empty($date)) {
$errors[] = "Data jest wymagana";
}
if (empty($student)) {
$errors[] = "Wybierz ucznia";
}
if (!in_array($status, $validStatuses)) {
$errors[] = "Nieprawidłowy status obecności";
}
// Walidacja formatu daty
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) {
$errors[] = "Nieprawidłowy format daty (YYYY-MM-DD)";
}
// Data nie może być z przyszłości
if ($date > date('Y-m-d')) {
$errors[] = "Data nie może być z przyszłości";
}

Statusy z etykietami i kolorami:

function getStatuses(): array {
return [
'present' => ['label' => 'Obecny', 'icon' => '', 'color' => '#27ae60'],
'absent' => ['label' => 'Nieobecny', 'icon' => '', 'color' => '#e74c3c'],
'late' => ['label' => 'Spóźniony', 'icon' => '', 'color' => '#f39c12'],
'excused' => ['label' => 'Usprawiedliwiony', 'icon' => '📋', 'color' => '#3498db'],
];
}
function getStatusLabel(string $status): string {
$statuses = getStatuses();
return $statuses[$status]['label'] ?? 'Nieznany';
}
function getStatusColor(string $status): string {
$statuses = getStatuses();
return $statuses[$status]['color'] ?? '#95a5a6';
}

Dodawanie wpisu obecności:

function addAttendance(array &$attendance, array $data): int {
$newId = empty($attendance) ? 1 : max(array_column($attendance, 'id')) + 1;
$newEntry = [
'id' => $newId,
'date' => $data['date'],
'student' => $data['student'],
'student_id' => $data['student_id'] ?? '',
'status' => $data['status'],
'notes' => $data['notes'] ?? '',
'recorded_by' => $data['recorded_by'] ?? 'System',
'created_at' => date('Y-m-d H:i:s'),
];
$attendance[] = $newEntry;
return $newId;
}

Podsumowanie obecności ucznia:

function getStudentSummary(array $attendance, string $student): array {
$studentRecords = array_filter($attendance, fn($a) => $a['student'] === $student);
$counts = [
'present' => 0,
'absent' => 0,
'late' => 0,
'excused' => 0,
];
foreach ($studentRecords as $record) {
$status = $record['status'];
if (isset($counts[$status])) {
$counts[$status]++;
}
}
$total = count($studentRecords);
$attended = $counts['present'] + $counts['late'];
$frequency = $total > 0 ? round(($attended / $total) * 100, 1) : 0;
return [
'student' => $student,
'total' => $total,
'counts' => $counts,
'frequency' => $frequency,
];
}

Podsumowanie dnia (frekwencja klasy):

function getDaySummary(array $attendance, string $date): array {
$dayRecords = array_filter($attendance, fn($a) => $a['date'] === $date);
$statusCounts = array_count_values(array_column($dayRecords, 'status'));
$total = count($dayRecords);
$present = ($statusCounts['present'] ?? 0) + ($statusCounts['late'] ?? 0);
$frequency = $total > 0 ? round(($present / $total) * 100, 1) : 0;
return [
'date' => $date,
'total' => $total,
'present' => $statusCounts['present'] ?? 0,
'absent' => $statusCounts['absent'] ?? 0,
'late' => $statusCounts['late'] ?? 0,
'excused' => $statusCounts['excused'] ?? 0,
'frequency' => $frequency,
];
}

Filtrowanie i sortowanie:

function filterByDate(array $attendance, string $date): array {
return array_filter($attendance, fn($a) => $a['date'] === $date);
}
function filterByStudent(array $attendance, string $student): array {
return array_filter($attendance, fn($a) => $a['student'] === $student);
}
function filterByStatus(array $attendance, string $status): array {
return array_filter($attendance, fn($a) => $a['status'] === $status);
}
function sortByDate(array $attendance, string $order = 'desc'): array {
usort($attendance, function($a, $b) use ($order) {
$result = strcmp($a['date'], $b['date']);
return $order === 'desc' ? -$result : $result;
});
return $attendance;
}

Generowanie raportu HTML (wariant C):

function generateReport(array $attendance, string $dateFrom, string $dateTo): string {
$filtered = array_filter($attendance, function($a) use ($dateFrom, $dateTo) {
return $a['date'] >= $dateFrom && $a['date'] <= $dateTo;
});
$students = array_unique(array_column($filtered, 'student'));
sort($students);
$html = '<!DOCTYPE html><html><head><meta charset="UTF-8">';
$html .= '<title>Raport obecności ' . $dateFrom . ' - ' . $dateTo . '</title>';
$html .= '<style>table { border-collapse: collapse; width: 100%; }';
$html .= 'th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }';
$html .= 'th { background: #333; color: white; }</style></head><body>';
$html .= '<h1>Raport obecności</h1>';
$html .= '<p>Okres: ' . $dateFrom . ' - ' . $dateTo . '</p>';
$html .= '<table><tr><th>Uczeń</th><th>Obecny</th><th>Nieobecny</th><th>Spóźniony</th><th>Frekwencja</th></tr>';
foreach ($students as $student) {
$summary = getStudentSummary($filtered, $student);
$html .= '<tr>';
$html .= '<td>' . htmlspecialchars($student) . '</td>';
$html .= '<td>' . $summary['counts']['present'] . '</td>';
$html .= '<td>' . $summary['counts']['absent'] . '</td>';
$html .= '<td>' . $summary['counts']['late'] . '</td>';
$html .= '<td>' . $summary['frequency'] . '%</td>';
$html .= '</tr>';
}
$html .= '</table></body></html>';
return $html;
}

Wykorzystaj lekcje!

Cotygodniowe spotkania podczas lekcji to idealny moment, by:

  • Pokazać postępy - nawet małe kroki się liczą
  • Wyjaśnić wątpliwości - pytaj, nie zgaduj
  • Skonsultować rozwiązania - feedback pomoże Ci się rozwijać

Pracuj iteracyjnie - lepiej mieć działający wariant A niż niedokończony C!