Mittwoch, 21 Januar 2026

Diese Woche am beliebtesten

Vertiefendes Material

Mini Timer

Einfacher Timer mit Start/Stopp-Funktion für mehrere Timer gleichzeitig. Letzte Laufzeiten werden automatisch in Textdateien gespeichert. Sofort einsatzbereit, keine Datenbank nötig.

<?php
define('TIMER_DIR', __DIR__ . '/timers/');
if(!is_dir(TIMER_DIR)) mkdir(TIMER_DIR);

function jsonResponse($data,$code=200){
    http_response_code($code);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode($data);
    exit;
}

function getTimers(){
    $timers=[];
    foreach(glob(TIMER_DIR.'*.txt') as $file){
        $data = json_decode(file_get_contents($file), true);
        $timers[] = $data;
    }
    return $timers;
}

function saveTimer($id,$name,$duration,$last_runtime){
    $data=['id'=>$id,'name'=>$name,'duration'=>$duration,'last_runtime'=>$last_runtime];
    file_put_contents(TIMER_DIR.$id.'.txt', json_encode($data));
}

if(isset($_GET['action'])){
    if($_GET['action']==='add'){
        $name = trim($_POST['name'] ?? 'Timer');
        $duration = intval($_POST['duration'] ?? 60);
        $id = time().rand(100,999);
        saveTimer($id,$name,$duration,0);
        jsonResponse(['success'=>true]);
    }
    if($_GET['action']==='list'){
        jsonResponse(getTimers());
    }
    if($_GET['action']==='update'){
        $id = intval($_POST['id'] ?? 0);
        $runtime = intval($_POST['runtime'] ?? 0);
        $timers = getTimers();
        foreach($timers as $t){
            if($t['id']==$id){
                saveTimer($id,$t['name'],$t['duration'],$runtime);
                break;
            }
        }
        jsonResponse(['success'=>true]);
    }
}
?>

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Dreamcodes Mini-Timer</title>
<style>
body{font-family:Arial,sans-serif;background:#f0f0f0;padding:20px;}
.timer{background:#fff;padding:15px;margin-bottom:10px;border-radius:8px;}
button{margin-left:5px;padding:5px 10px;}
</style>
</head>
<body>
<h2>Mini-Timer / Countdown</h2>
<form id="addTimerForm">
<input type="text" name="name" placeholder="Name">
<input type="number" name="duration" placeholder="Sekunden" value="60">
<button type="submit">Hinzufügen</button>
</form>
<div id="timers"></div>
<script>
let timersData = {};

async function fetchTimers(){
    const resp = await fetch('?action=list');
    const data = await resp.json();
    const container = document.getElementById('timers');
    container.innerHTML='';
    data.forEach(t=>{
        const div = document.createElement('div');
        div.className='timer';
        div.id='timer-'+t.id;
        div.innerHTML=`<strong>${t.name}</strong> - <span id='time-${t.id}'>${t.duration}</span> Sekunden
<button onclick='startTimer(${t.id}, ${t.duration})'>Start</button>
<button onclick='stopTimer(${t.id})'>Stopp</button>
`;
        container.appendChild(div);
        timersData[t.id]={duration:t.duration, interval:null, remaining:t.duration};
    });
}

async function startTimer(id,duration){
    stopTimer(id);
    timersData[id].remaining=duration;
    timersData[id].interval=setInterval(()=>{
        timersData[id].remaining--;
        document.getElementById('time-'+id).textContent=timersData[id].remaining;
        if(timersData[id].remaining<=0){
            stopTimer(id);
            saveRuntime(id,duration);
        }
    },1000);
}

function stopTimer(id){
    if(timersData[id].interval){
        clearInterval(timersData[id].interval);
        timersData[id].interval=null;
        saveRuntime(id,timersData[id].duration - timersData[id].remaining);
    }
}

async function saveRuntime(id,runtime){
    const fd=new FormData(); fd.append('id',id); fd.append('runtime',runtime);
    await fetch('?action=update',{method:'POST',body:fd});
}

document.getElementById('addTimerForm').addEventListener('submit',async(e)=>{
    e.preventDefault();
    const formData=new FormData(e.target);
    await fetch('?action=add',{method:'POST',body:formData});
    e.target.reset();
    fetchTimers();
});

fetchTimers();
</script>
</body>
</html>
Dreamcodes Redaktion
Dreamcodes Redaktion
Qualität als Standard. Verantwortung als Prinzip. Jede Ressource auf Dreamcodes basiert auf geprüften Best Practices und fundierter Praxiserfahrung. Unser Anspruch ist ein belastbares Fundament statt experimenteller Lösungen. Die Integration und Absicherung der Inhalte liegt in Ihrem Ermessen. Wir liefern die fachliche Basis, die Verantwortung für den produktiven Einsatz verbleibt bei Ihnen.
Vorheriges Tutorial
Nächstes Tutorial

Vielleicht einen Blick WERT?