Dienstag, 31 März 2026

Diese Woche am beliebtesten

Vertiefendes Material

Sprit Monitor Pro Script

Die professionelle Lösung für den regionalen Sprit Preisvergleich. Unser Php Script bietet eine lückenlose Live Abfrage der aktuellen Kraftstoffpreise direkt über die Markttransparenzstelle (MTS-K). Integriert in eine interaktive Google Maps Umgebung, ermöglicht das Script einen präzisen Vergleich von Super E5, E10 und Diesel im gewählten Umkreis. Mit Fokus auf Usability und technischer Substanz bietet das Tool automatische Standorterkennung, Preis Sortierung und ein schickes Interface für höchste Ansprüche. API Keys für Google und Tankerkönig werden benötigt.

Code als Setup.php abspeichern. Nach einmaligem Aufruf wird die index, Api, Script.js und Style.css automatisch erstellt und die Setup Datei gelöscht.

<?php
$tanker_key = "DEIN_TANKERKOENIG_API_KEY"; 
$google_key = "DEIN_GOOGLE_MAPS_API_KEY";

if (!is_dir('fonts')) mkdir('fonts', 0755);
$font_sources = ['outfit-reg.woff2' => 'https://fonts.gstatic.com/s/outfit/v11/QGYsz_O5rkz2mS4_OTuSfA.woff2', 'outfit-bold.woff2' => 'https://fonts.gstatic.com/s/outfit/v11/QGYsz_O5rkz2mS4_ObeSfA.woff2'];

foreach ($font_sources as $name => $url) {
    if (!file_exists("fonts/$name")) {
        $ch = curl_init($url); $fp = fopen("fonts/$name", 'wb');
        curl_setopt($ch, CURLOPT_FILE, $fp); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_exec($ch); curl_close($ch); fclose($fp);
    }
}
$css_content = <<<EOD
@font-face { font-family: 'Outfit'; src: url('fonts/outfit-reg.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Outfit'; src: url('fonts/outfit-bold.woff2') format('woff2'); font-weight: 900; font-style: normal; font-display: swap; }
:root { --accent: #d4af37; --bg: #0a0a0b; --glass: rgba(255, 255, 255, 0.03); --border: rgba(255, 255, 255, 0.08); }
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: 'Outfit', sans-serif; background: var(--bg); color: #fff; overflow-x: hidden; padding: 2rem; min-height: 100vh; display: flex; flex-direction: column; }
.container { max-width: 1200px; margin: 0 auto; flex: 1; width: 100%; }
header { display: flex; justify-content: space-between; align-items: flex-end; margin-bottom: 3rem; }
.brand-box h1 { font-size: clamp(1.5rem, 4vw, 3rem); font-weight: 900; text-transform: uppercase; letter-spacing: -1px; background: linear-gradient(135deg, #d4af37 0%, #f9e29c 50%, #b38728 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.subtitle { color: #666; text-transform: uppercase; letter-spacing: 2px; font-size: 0.7rem; margin-top: 0.5rem; line-height: 1.4; max-width: 400px; }
.clock-box { text-align: right; }
#clock { font-size: 1.5rem; color: #444; font-family: monospace; }
.status-tag { font-size: 9px; color: var(--accent); letter-spacing: 2px; }
.main-grid { display: grid; grid-template-columns: 1.5fr 1fr; gap: 2rem; margin-bottom: 4rem; }
@media (max-width: 900px) { .main-grid { grid-template-columns: 1fr; } .clock-box { display: none; } }
.glass-panel { background: var(--glass); backdrop-filter: blur(20px); border: 1px solid var(--border); border-radius: 24px; position: relative; overflow: hidden; }
#map { height: 500px; background: #111; filter: grayscale(1) invert(0.9) contrast(1.1); }
.feed { height: 500px; overflow-y: auto; padding-right: 10px; }
.feed::-webkit-scrollbar { width: 4px; }
.feed::-webkit-scrollbar-thumb { background: var(--accent); border-radius: 10px; }
.feed-loading { text-align: center; margin-top: 100px; color: #444; }
.price-card { background: var(--glass); border: 1px solid var(--border); border-radius: 20px; padding: 1.5rem; display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem; transition: 0.3s ease; opacity: 0; transform: translateY(20px); }
.price-card.show { opacity: 1; transform: translateY(0); }
.price-card:hover { transform: translateX(10px); border-color: var(--accent); background: rgba(255,255,255,0.06); }
.station-info h2 { font-weight: 800; font-size: 1.2rem; }
.station-addr { color: #666; font-size: 0.7rem; margin-top: 4px; text-transform: uppercase; }
.station-dist { color: #444; font-size: 9px; margin-top: 8px; font-family: monospace; }
.price-box { text-align: right; }
.price-val { font-size: 2.2rem; font-weight: 900; }
.gold-text { background: linear-gradient(135deg, #d4af37, #f9e29c); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.btn-group { position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); display: flex; gap: 10px; padding: 8px; background: rgba(0,0,0,0.5); backdrop-filter: blur(10px); border-radius: 16px; border: 1px solid var(--border); z-index: 10; }
button { padding: 10px 20px; border-radius: 12px; border: none; font-weight: 700; cursor: pointer; transition: 0.3s; background: transparent; color: #888; }
button.active { background: #fff; color: #000; }
.best-label { font-size: 9px; border: 1px solid var(--accent); color: var(--accent); padding: 2px 8px; text-transform: uppercase; margin-left: 10px; border-radius: 10px; }
.nav-link { color: var(--accent); text-decoration: none; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 1px; }
.pulse { animation: pulse 2s infinite; }
@keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(212, 175, 55, 0.4); } 70% { box-shadow: 0 0 0 10px rgba(212, 175, 55, 0); } 100% { box-shadow: 0 0 0 0 rgba(212, 175, 55, 0); } }
footer { padding: 2rem 0; border-top: 1px solid var(--border); text-align: center; margin-top: auto; }
.footer-link { color: #555; text-decoration: none; font-size: 0.7rem; letter-spacing: 2px; text-transform: uppercase; transition: 0.3s; }
.footer-link:hover { color: var(--accent); }
.footer-link span { font-weight: 900; }
.install-ui { height: 100vh; display: flex; flex-direction: column; justify-content: center; align-items: center; text-align: center; }
.timer-circle { width: 120px; height: 120px; border-radius: 50%; border: 2px solid var(--border); display: flex; align-items: center; justify-content: center; font-size: 3rem; font-weight: 900; color: var(--accent); margin: 2rem 0; position: relative; }
.timer-circle::after { content: ''; position: absolute; top: -5px; left: -5px; right: -5px; bottom: -5px; border: 2px solid var(--accent); border-radius: 50%; border-left-color: transparent; animation: spin 1s linear infinite; }
@keyframes spin { 100% { transform: rotate(360deg); } }
EOD;
file_put_contents('style.css', $css_content);

$js_content = <<<EOD
let map, markers = [], fType = 'e5', acc = '#d4af37';
const $ = id => document.getElementById(id);
async function initMap() {
    map = new google.maps.Map($("map"), { zoom: 14, center: { lat: 52.52, lng: 13.4 }, disableDefaultUI: true, styles: [{elementType: "geometry", stylers: [{color: "#212121"}]}, {elementType: "labels.text.fill", stylers: [{color: "#757575"}]}, {featureType: "road", elementType: "geometry", stylers: [{color: "#303030"}]}] });
    navigator.geolocation?.getCurrentPosition(p => { const loc = {lat: p.coords.latitude, lng: p.coords.longitude}; map.setCenter(loc); load(loc); }, () => load({lat: 52.52, lng: 13.4}));
}
const load = async l => { const r = await fetch(`api.php?lat=\${l.lat}&lng=\${l.lng}`), d = await r.json(); if (d.status === "ok") render(d.stations); };
const render = sts => {
    const list = $("station-feed"); list.innerHTML = ""; markers.forEach(m => m.setMap(null)); markers = [];
    sts.sort((a, b) => (a[fType] || 99) - (b[fType] || 99)).forEach((s, i) => {
        const isB = i === 0 && s[fType] > 0, pr = s[fType] ? s[fType].toFixed(2) + '<span style="font-size:0.5em">9</span>' : 'N/A';
        const m = new google.maps.Marker({ position: {lat: s.lat, lng: s.lng}, map, icon: {path: google.maps.SymbolPath.CIRCLE, fillColor: isB ? acc : '#fff', fillOpacity: 1, strokeWeight: 0, scale: isB ? 10 : 6} }); markers.push(m);
        const c = document.createElement('div'); c.className = `price-card \${isB ? 'pulse' : ''}`;
        c.innerHTML = `<div class="station-info"><div style="display:flex;align-items:center;"><h2>\${s.brand||'Station'}</h2>\${isB?'<span class="best-label">Bestpreis</span>':''}</div><div class="station-addr">\${s.street}, \${s.place}</div><div class="station-dist">\${s.dist} KM DISTANCE</div></div><div class="price-box"><div class="price-val \${isB?'gold-text':''}">\${pr}€</div><a href="http://googleusercontent.com/maps.google.com/7{s.lat},\${s.lng}" target="_blank" class="nav-link">Navigate →</a></div>`;
        list.appendChild(c); setTimeout(() => c.classList.add('show'), i * 40);
    });
};
const changeFuel = (t, b) => { fType = t; document.querySelectorAll('button').forEach(btn => btn.classList.remove('active')); b.classList.add('active'); navigator.geolocation.getCurrentPosition(p => load({lat: p.coords.latitude, lng: p.coords.longitude})); };
setInterval(() => $("clock") && ($("clock").innerText = new Date().toLocaleTimeString('de-DE')), 1000);
EOD;
file_put_contents('script.js', $js_content);
file_put_contents('api.php', "<?php header('Content-Type: application/json'); \$lat = \$_GET['lat']; \$lng = \$_GET['lng']; \$url = \"https://creativecommons.tankerkoenig.de/json/list.php?lat=\$lat&lng=\$lng&rad=10&sort=dist&type=all&apikey=$tanker_key\"; echo @file_get_contents(\$url); ?>");
$index_content = <<<EOD
<!DOCTYPE html>
<html lang="de">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Sprit Monitor Pro | Preisvergleich</title><link rel="stylesheet" href="style.css"></head>
<body>
<div class="container">
    <header><div class="brand-box"><h1>Sprit Monitor Pro</h1><div class="subtitle">Benzin und Diesel Preisvergleich mit Maps Integration</div></div><div class="clock-box"><div id="clock">00:00:00</div><div class="status-tag">SYSTEM ONLINE</div></div></header>
    <div class="main-grid"><div class="glass-panel"><div id="map"></div><div class="btn-group"><button onclick="changeFuel('e5', this)" class="active">E5</button><button onclick="changeFuel('e10', this)">E10</button><button onclick="changeFuel('diesel', this)">Diesel</button></div></div><div class="feed" id="station-feed"><div class="feed-loading">Initialisiere Sensoren...</div></div></div>
</div>
<footer><a href="https://www.dreamcodes.net" target="_blank" class="footer-link">Powered by <span>Dreamcodes</span></a></footer>
<script src="https://maps.googleapis.com/maps/api/js?key=$google_key&callback=initMap" async defer></script><script src="script.js"></script>
</body>
</html>
EOD;
file_put_contents('index.php', $index_content);
unlink(__FILE__);
?>
<!DOCTYPE html>
<html lang="de">
<head><meta charset="UTF-8"><title>Setup abgeschlossen</title><link rel="stylesheet" href="style.css"></head>
<body>
    <div class="install-ui"><h1 class="gold-text" style="font-size: 3rem; font-weight: 900;">SYSTEM BEREIT</h1><p style="color: #666; letter-spacing: 2px;">INSTALLER GELÖSCHT. WEITERLEITUNG IN...</p><div class="timer-circle" id="timer">10</div><p style="color: #444; font-size: 0.8rem;">Initialisiere Dashboard & API Schnittstellen</p></div>
    <script>let timeLeft = 10; const timerEl = document.getElementById('timer'); const countdown = setInterval(() => { timeLeft--; timerEl.innerText = timeLeft; if(timeLeft <= 0) { clearInterval(countdown); window.location.href = 'index.php'; } }, 1000);</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

Vielleicht einen Blick WERT?