← Terug naar Toolbox

QUICK REFERENCE

Syntax zonder zoekwerk

Zoek op een begrip, filter per technologie en kopieer een voorbeeld. Pas de code daarna bewust aan je eigen project aan.

/

HTML

Basisdocument

Start elke pagina met een geldige structuur.

<!doctype html>
<html lang="nl">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Paginatitel</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <h1>Welkom</h1>
  <script src="app.js" defer></script>
</body>
</html>

Let op: gebruik defer zodat JavaScript pas na de HTML wordt uitgevoerd.

HTML

Tekst en lijsten

<h1>Hoofdtitel</h1>
<h2>Tussentitel</h2>
<p>Tekst met <strong>belang</strong> en <em>nadruk</em>.</p>
<ul>
  <li>Eerste item</li>
  <li>Tweede item</li>
</ul>

Let op: kies kopniveaus op betekenis, niet op lettergrootte.

HTML

Links en afbeeldingen

<a href="contact.html">Contact</a>
<a href="https://example.com" target="_blank" rel="noopener">Website</a>

<figure>
  <img src="images/team.jpg" alt="Het WebCraft-team">
  <figcaption>Samen bouwen.</figcaption>
</figure>

Let op: schrijf een nuttige alt-tekst; gebruik alt="" voor puur decoratieve beelden.

HTML

Semantische structuur

<header>…</header>
<nav aria-label="Hoofdnavigatie">…</nav>
<main>
  <section>
    <h2>Onderwerp</h2>
    <article>…</article>
  </section>
</main>
<footer>…</footer>

Let op: er is normaal maar één zichtbaar hoofdgebied met <main>.

HTML

Tabel

<table>
  <caption>Resultaten</caption>
  <thead><tr><th scope="col">Naam</th><th scope="col">Score</th></tr></thead>
  <tbody><tr><td>Noor</td><td>18/20</td></tr></tbody>
</table>

Let op: gebruik tabellen voor gegevens, nooit om een pagina op te maken.

HTML

Formulier

<form id="contact-form">
  <label for="email">E-mail</label>
  <input id="email" name="email" type="email" required>

  <label for="bericht">Bericht</label>
  <textarea id="bericht" name="bericht"></textarea>
  <button type="submit">Versturen</button>
</form>

Let op: de for van een label moet gelijk zijn aan het id van het veld.

CSS

Selectors

p { color: #172033; }          /* element */
.card { padding: 1rem; }       /* class */
#menu { display: flex; }       /* id */
.card h2 { margin: 0; }        /* binnen card */
.button:hover { translate: 0 -2px; }
input:focus-visible { outline: 3px solid #d6006d; }

Let op: geef styling meestal met classes; vermijd onnodig specifieke selectors.

CSS

Boxmodel

* { box-sizing: border-box; }

.card {
  width: min(100%, 32rem);
  margin: 1.5rem auto;
  padding: 1.25rem;
  border: 1px solid #e3e5ea;
  border-radius: 1rem;
}

Let op: verticale marges kunnen samenvallen; gebruik in layouts vaak gap.

CSS

Flexbox

.container {
  display: flex;
  align-items: center;       /* dwarsas */
  justify-content: space-between; /* hoofdas */
  gap: 1rem;
  flex-wrap: wrap;
}

.item { flex: 1 1 15rem; }

Gebruik voor: één rij of kolom en het uitlijnen van onderdelen.

CSS

CSS Grid

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1.25rem;
}

.breed { grid-column: 1 / -1; }

Gebruik voor: layouts met rijen én kolommen.

CSS

Responsive ontwerp

img { max-width: 100%; height: auto; }
h1 { font-size: clamp(2rem, 6vw, 4.5rem); }

@media (max-width: 48rem) {
  .layout { grid-template-columns: 1fr; }
}

Let op: test ook tussen de vaste schermbreedtes, niet alleen op één telefoon.

CSS

Variabelen

:root {
  --brand: #d6006d;
  --ink: #172033;
  --space: 1rem;
}

.button {
  color: white;
  background: var(--brand);
  padding: calc(var(--space) * .75) var(--space);
}

Let op: geef variabelen namen op basis van hun functie.

JS

Variabelen en strings

const naam = 'Alex';
let score = 0;
const geslaagd = true;

score += 1;
const melding = `Hallo ${naam}, je score is ${score}.`;

Let op: gebruik standaard const; alleen let wanneer de waarde opnieuw wordt toegewezen.

JS

Voorwaarden

if (score >= 10 && aanwezig) {
  console.log('Geslaagd');
} else {
  console.log('Nog even oefenen');
}

const label = gebruikersnaam ?? 'Gast';

Let op: vergelijk strikt met === en !==.

JS

Functies

const berekenTotaal = (prijs, aantal = 1) => {
  return prijs * aantal;
};

const totaal = berekenTotaal(8.5, 3);
const verdubbel = getal => getal * 2;

Let op: laat een functie één duidelijke taak uitvoeren.

JS

Arrays en objecten

const leerling = { naam: 'Noor', score: 16 };
const { naam, score } = leerling;

const scores = [8, 12, 16, 19];
const geslaagd = scores.filter(score => score >= 10);
const dubbel = scores.map(score => score * 2);
const eersteTopscore = scores.find(score => score >= 16);

Let op: map maakt een nieuwe array; forEach niet.

JS

DOM aanpassen

const titel = document.querySelector('h1');
const kaarten = document.querySelectorAll('.card');

titel.textContent = 'Nieuwe titel';
titel.classList.add('accent');
titel.setAttribute('aria-live', 'polite');

kaarten.forEach(kaart => kaart.classList.toggle('actief'));

Let op: controleer of een element bestaat of gebruik ?. wanneer dat niet zeker is.

JS

Events en formulieren

const formulier = document.querySelector('#contact-form');

formulier?.addEventListener('submit', event => {
  event.preventDefault();
  const data = new FormData(formulier);
  const email = data.get('email')?.trim();
  console.log(email);
});

Let op: schrijf 'click' zonder on en geef de functienaam zonder haakjes door.

JS

Debuggen

console.log('Waarde:', waarde);
console.table(leerlingen);
console.log(typeof invoer);

try {
  voerActieUit();
} catch (error) {
  console.error(error.message);
}

Werkwijze: reproduceer → lees de melding → test één hypothese → controleer opnieuw.

JS

API’s en fetch

const response = await fetch(url);
if (!response.ok) {
  throw new Error(`HTTP ${response.status}`);
}
const data = await response.json();

const postResponse = await fetch(endpoint, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ country: 'Belgium' })
});

Let op: voorzie loading, error en result; zet nooit een geheime sleutel in publieke frontendcode.

BS

Bootstrap koppelen

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="style.css">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js" defer></script>

Let op: eigen CSS komt na Bootstrap.

BS

Responsive grid

<div class="container">
  <div class="row g-4">
    <article class="col-12 col-md-6 col-lg-4">…</article>
  </div>
</div>

Patroon: container → row → col. Begin mobiel met col-12.

BS

Utilities

py-5              /* verticale padding */
mb-3              /* margin onderaan */
d-flex            /* Flexbox */
gap-3             /* ruimte tussen items */
d-none d-md-block /* tonen vanaf md */

Leesregel: eigenschap + zijde + breakpoint + waarde.

BS

Navbar en collapse

<button class="navbar-toggler" type="button"
  data-bs-toggle="collapse" data-bs-target="#menu"
  aria-controls="menu" aria-expanded="false">…</button>
<div class="collapse navbar-collapse" id="menu">…</div>

Debug: target en id moeten exact gelijk zijn; de bundle moet geladen zijn.

BS

Formulieren

<label class="form-label" for="email">E-mail</label>
<input class="form-control" id="email" name="email"
  type="email" required>
<div class="invalid-feedback">Vul een geldig e-mailadres in.</div>

Let op: styling vervangt correcte labels en inputtypes niet.

BS

Componenten

btn btn-primary
card h-100
badge text-bg-dark
accordion
modal fade
offcanvas offcanvas-start
alert alert-info

Kies bewust: gebruik een component alleen wanneer het echt helpt.

PHP

PHP 8-basis

<?php
declare(strict_types=1);

const APP_NAME = 'ProjectHub';
$title = 'Mijn project';
$tags = ['PHP', 'MySQL'];

function e(string|int|null $value): string
{
    return htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8');
}
?>
<h1><?= e($title) ?></h1>

Let op: escape dynamische waarden bij HTML-output, niet wanneer je ze in de database bewaart.

PHP

Eerst data, dan HTML

Gebruik de MVC-denkwijze zonder een strikt framework.

<?php
declare(strict_types=1);
require_once __DIR__ . '/../src/bootstrap.php';

// 1. Request/controller
$filter = trim($_GET['filter'] ?? '');

// 2. Model/repository
$items = findItems(database(), $filter);

// 3. Viewdata
$pageTitle = 'Overzicht';
$itemCount = count($items);

// 4. View
require __DIR__ . '/../views/items/index.php';

WebCraft-afspraak: de view toont voorbereide variabelen en start geen query's.

PHP

Request valideren en redirecten

$id = filter_input(INPUT_POST, 'id', FILTER_VALIDATE_INT);

if (!is_int($id) || $id < 1) {
    http_response_code(400);
    exit('Ongeldige id.');
}

header('Location: detail.php?id=' . $id, true, 303);
exit;

Let op: browservalidatie helpt de gebruiker; de server valideert altijd opnieuw.

PDO

PDO-verbinding

$dsn = 'mysql:host=127.0.0.1;port=3306;dbname=projecthub;charset=utf8mb4';

$pdo = new PDO($dsn, DB_USER, DB_PASSWORD, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES => false,
]);

Let op: bewaar lokale credentials buiten public en buiten Git.

PDO

Prepared statement

$statement = $pdo->prepare(
    'SELECT id, title FROM projects WHERE id = :id'
);
$statement->bindValue(':id', $id, PDO::PARAM_INT);
$statement->execute();

$project = $statement->fetch();

WebCraft-afspraak: prepare → expliciet binden met PDO-type → execute zonder argumenten.

CRUD

Write en soft delete

// Create
$statement = $pdo->prepare(
    'INSERT INTO projects (title) VALUES (:title)'
);
$statement->bindValue(':title', $title, PDO::PARAM_STR);
$statement->execute();
$id = (int) $pdo->lastInsertId();

// Archive
$statement = $pdo->prepare(
    'UPDATE projects SET active = FALSE WHERE id = :id'
);
$statement->bindValue(':id', $id, PDO::PARAM_INT);
$statement->execute();

Let op: wijzig gegevens via POST en gebruik na succes een 303-redirect.

PDO

Transactie

$pdo->beginTransaction();

try {
    // Meerdere afhankelijke writes
    $pdo->commit();
} catch (Throwable $error) {
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }
    throw $error;
}

Gebruik voor: één gebruikersactie die alleen geldig is wanneer alle writes slagen.

PDO

Veilig sorteren en pagineren

$allowedSorts = ['title', 'created_at'];
$sort = in_array($requestedSort, $allowedSorts, true)
    ? $requestedSort
    : 'created_at';

$statement = $pdo->prepare(
    "SELECT id, title FROM projects
     ORDER BY $sort DESC LIMIT :limit OFFSET :offset"
);
$statement->bindValue(':limit', $limit, PDO::PARAM_INT);
$statement->bindValue(':offset', $offset, PDO::PARAM_INT);
$statement->execute();

Let op: bind waarden; controleer SQL-structuur zoals kolomnamen met een allowlist.

AUTH

Veilige login en sessie

session_set_cookie_params([
    'httponly' => true,
    'secure' => true,
    'samesite' => 'Lax',
]);
session_start();

if (password_verify($password, $user['password_hash'])) {
    session_regenerate_id(true);
    $_SESSION['user_id'] = (int) $user['id'];
}

Let op: gebruik password_hash() en password_verify(); bewaar nooit platte wachtwoorden.

CSRF

CSRF-token

$_SESSION['csrf'] ??= bin2hex(random_bytes(32));

// In het formulier
<input type="hidden" name="csrf"
  value="<?= e($_SESSION['csrf']) ?>">

// Bij elke wijzigende POST-request
$token = $_POST['csrf'] ?? '';
if (!hash_equals($_SESSION['csrf'], $token)) {
    http_response_code(403);
    exit('Ongeldige aanvraag.');
}

Let op: een CSRF-token vervangt geen autorisatiecontrole.

GUARD

Autorisatie op de server

function requireRole(string ...$allowed): void
{
    $role = $_SESSION['role'] ?? null;
    if (!is_string($role) || !in_array($role, $allowed, true)) {
        http_response_code(403);
        exit('Geen toegang.');
    }
}

requireRole('admin', 'teacher');

Let op: een verborgen knop is geen beveiliging; controleer elke route server-side.

RELEASE

Productiecheck

□ display_errors uit, logging aan
□ unieke productiegeheimen buiten public en Git
□ debugroutes en testaccounts verwijderd
□ migraties en smoke tests uitgevoerd
□ database én uploads geback-upt
□ restore in aparte omgeving getest
□ 403, 404 en 500 geven veilige feedback

Bewijs: noteer test, resultaat, datum en verantwoordelijke bij elke releasecheck.