Personal Diary System with PHP

Learn to create a dynamic personal diary with file manipulation in PHP

Download Example Code 1 Download Example Code 2 View submission exercise

What is a Personal Diary System?

Create Entries

Automatically generates new diary entries

Save to Files

Each entry is stored in a separate PHP file

Entry Management

View and organize all your entries from a central menu

Automatic Numbering

The system numbers the days consecutively

System Architecture

📄 diario.php

Main page with form and list of entries

📝 registro.php

Processes the form and creates new entries

📚 menu.php

Navigation menu across all entries

📁 registros/

Directory where all entries are stored

Current Status of the Demo Entry

File: diario_demo.php EXISTS

Size: 1114 bytes

Last modified: 2026-09-10 16:12:04

Current content:

<?php include_once '../database/config.php'; ?>
<?php
// Mi Diario Personal - Entrada de ejemplo
$fecha = date('Y-m-d H:i:s');
$nombre = 'Usuario Demo';
?>
<html>
<head>
    <!-- FOUC-FIX-DARKTHEME: evita el flash de modo claro al cargar/navegar con el modo oscuro activado -->
    <style>html.dark-theme,html.dark-theme body{background-color:#121212 !important;color-scheme:dark}</style>
    <script>(function(){try{var t=localStorage.getItem('theme');if(t==='dark'||(t===null&&window.matchMedia('(prefers-color-scheme: dark)').matches)){var h=document.documentElement;h.classList.add('dark-theme');h.style.colorScheme='dark';}}catch(e){}})();</script>

    <title><?php echo t('Mi Diario'); ?></title>
</head>
<body>
    <h1><?php echo t('Mi Diario Personal'); ?></h1>
    <p><strong><?php echo t('Fecha'); ?>:</strong> <?php echo $fecha; ?></p>
    <p><strong><?php echo t('Nombre'); ?>:</strong> <?php echo $nombre; ?></p>
    <div>
        <h2><?php echo t('Mis pensamientos de hoy:'); ?></h2>
        <p><?php echo t('Esta es una entrada de ejemplo en mi diario personal.'); ?></p>
    </div>
</body>
</html>

Try the Diary System

Use the following controls to try the personal diary functions in real time:

Diary Control Panel

System Code Explained

Function to Create Entries

<?php
function crearArchivoDia($numero_dia, $nombre, $apellido, $observaciones, $fecha) {
    $contenido_archivo = '<html>
<head>
    <title>Día '.$numero_dia.'</title>
    <link rel="stylesheet" href="../template/css/default.css">
</head>
<body>
    <div class="contenedor-pagina">
        <div class="encabezado-pagina">
            <h1>📅 Día '.$numero_dia.'</h1>
            <a href="../menu.php" class="boton-volver">← Volver al Menú</a>
        </div>
        
        <div class="tarjeta-entrada">
            <div class="info-entrada">
                <p><strong>Fecha:</strong> '.$fecha.'</p>
                <p><strong>Nombre:</strong> '.$nombre.' '.$apellido.'</p>
            </div>
            
            <div class="seccion-observaciones">
                <h3>📝 Lo que hice hoy:</h3>
                <div class="contenido-observaciones">
                    '.nl2br($observaciones).'
                </div>
            </div>
        </div>
    </div>
</body>
</html>';

    $nombre_archivo = "registros/Dia $numero_dia.php";
    file_put_contents($nombre_archivo, $contenido_archivo);
}
?>

Key function: file_put_contents() creates the file automatically if it doesn't exist

nl2br(): Converts line breaks into <br> for HTML

structure HTML: A full page is generated HTML for each entry

Form Processing

<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // Sanitize input    $nombre = htmlspecialchars($_POST['nombre']);
    $apellido = htmlspecialchars($_POST['apellido']);
    $observaciones = htmlspecialchars($_POST['observaciones']);
    $fecha = date('Y-m-d H:i:s');
    
    // Get next day number    $numero_dia = obtenerProximoDia();
    
    // Create file    crearArchivoDia($numero_dia, $nombre, $apellido, $observaciones, $fecha);
    
    // Redirect to menu    header("Location: menu.php?creado=$numero_dia");
    exit();
}
?>

htmlspecialchars(): Prevents XSS by escaping special characters

header(): Redirects the user after processing the form

date(): Gets the server's current date and time

Function to List Entries

<?php
function obtenerDiasRegistrados() {
    $carpeta_registros = "registros";
    if (!file_exists($carpeta_registros)) {
        mkdir($carpeta_registros, 0777, true);
    }
    $archivos = glob("$carpeta_registros/Dia *.php");
    $dias = [];
    foreach ($archivos as $archivo) {
        preg_match('/Dia (\d+)\.php/', $archivo, $coincidencia);
        if (isset($coincidencia[1])) {
            $dias[] = $coincidencia[1];
        }
    }
    rsort($dias);
    return $dias;
}
?>

glob(): Searches for files matching the pattern "Dia *.php"

preg_match(): Extracts the day number from the file name

rsort(): Sorts the days from highest to lowest

mkdir(): Creates the directory if it doesn't exist

Exercises to Practice

Exercise 1: Add Categories

Modify the system so each entry can have a category (Work, Personal, Study, etc.)

Suggested solution:
// Add category field to the form<select name="categoria">
    <option value="personal">Personal</option>
    <option value="trabajo">Trabajo</option>
    <option value="estudio">Estudio</option>
</select>

// In crearArchivoDia(), include the category$contenido_archivo = '...<p><strong>Categoría:</strong> '.$categoria.'...';

// Show the category in the display

Exercise 2: Search Entries

Implement a search system that lets you find entries by keywords

Suggested solution:
function buscarEnEntradas($termino) {
    $entradas = obtenerDiasRegistrados();
    $resultados = [];
    foreach ($entradas as $dia) {
        $contenido = file_get_contents("registros/Dia $dia.php");
        if (stripos($contenido, $termino) !== false) {
            $resultados[] = $dia;
        }
    }
    return $resultados;
}

// In the search form<form method="GET" action="buscar.php">
    <input type="text" name="q" placeholder="Buscar en entradas...">
    <button type="submit">Find</button>
</form>

Exercise 3: Automatic Backup

Create a function to back up all entries into a ZIP

Suggested solution:
function crearBackupDiario() {
    $zip = new ZipArchive();
    $backup_file = 'backup_diario_' . date('Y-m-d') . '.zip';
    
    if ($zip->open($backup_file, ZipArchive::CREATE) === TRUE) {
        $entradas = glob("registros/*.php");
        foreach ($entradas as $entrada) {
            $zip->addFile($entrada, basename($entrada));
        }
        $zip->close();
        return $backup_file;
    }
    return false;
}

// Download the backupheader('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="'.$backup_file.'"');
readfile($backup_file);

Complete Workflow

1

User fills out the form

The user enters name, last name and remarks for the day

2

PHP processes the data

The server sanitizes the data and determines the next day number

3

The file is created

A new file is generated PHP with the diary entry

4

Redirection to the menu

The user is redirected to the main menu where they can see all their entries