Een model is een object die gerelateerd is aan een database tabel.
Voorbeeld model User (let op naam is in enkelvoud en met hoofdletter) heeft in de database de tabel 'users'
Omdat we met models object georienteerd programmeren is het mogelijk om overerving te gebruiken. Elke model moet kunnen worden aangemaakt, opgeslagen, gewijzigd etc.
Dit kunnen we één keer doen in een Model class. Deze Model class kunnen we als blauwdruk voor onze User model of Bericht model gebruiken.
Het is netjes om al je Models in een directory 'models' te zetten. Dit is overzichtelijk, maar niet noodzakelijk.
Een voorbeeld van een user Model
<?php class User extends Model { protected $table = "users"; }
Je ziet dat er 'extends Model' achter staat. Dat neemt alle eigenschappen van Model over.
Omdat je alle bestanden moet kunnen gebruiken. Moet je deze wel allemaal toevoegen aan je index.php onder de require van Database.php.
require "Model.php"; require "models/User.php"; require "models/Post.php";
Je kan met je Model queries bouwen. Hieronder een voorbeeldje
//query op users tabel $users = (new User()) ->where('voornaam', 'LIKE', '%p%') //voornaam LIKE '%p%' ->where('role', 'user') // role = 'user' ->whereNull('tussenvoegsel') // tussenvoegsel IS NULL ->get(); //uitvoeren van de query dd($users);
$users = (new User) ->limit(3) ->get();
Zal maximaal 3 users tonen.
$users = (new User)->all(); dd($users);
//aanmaken van een user $user = (new User())->create([ 'name' => 'Piet Puck', 'email' => 'testttw@mail.nl', 'password' => password_hash('password', PASSWORD_BCRYPT) ]); dd($user);
//zoeken van een user op id $user = (new User)->find(2); dd($user);
$user = (new User)->find(2); //voornaam van de gebruiker op het scherm schrijven echo $user->voornaam;
$user = (new User)->find(2); //naam wijzigen $user->name = 'John Doe'; //opslaan in database (alleen als er werkelijk iets gewijzigd is) $user->save();
//user met id=6 ophalen $user = (new User)->find(6); //de zojuist opgehaalde user verwijderen uit de database $user->delete();
Bij een User zullen we vaak de volledige naam op het scherm willen tonen. We kunnen hier een methode toevoegen aan User.php
<?php class User extends Model { protected $table = "users"; public function name(){ return $this->voornaam." ". $this->tussenvoegsel." ". $this->achternaam; } }
Let op dat er voor bovenstaande code wel velden in de database moeten bestaan met de namen 'voornaam', 'tussenvoegsel' en 'achternaam' deze velden zijn in onze default database niet aanwezig. De code zal dan ook fouten opleveren bij aanroep.
Nu kun je in je code een user selecteren en snel de naam op het scherm schrijven
$user = (new User)->find(4); echo $user->name();
Soms wil je graag even zien welke queries er allemaal worden uitgevoerd. Dat kan door de dumpQuerLog() methode te gebruiken. Dit zal alle uitvoerde queries op het scherm schrijven en het script verder afbreken.
$user = (new User)->find(2); //uitgevoerde queries bekijken $user->dumpQueryLog();
Dit script is de 'parent' en vrij ingewikkeld qua code. Maar dat is niet erg, want je hoeft dit ook niet allemaal te snappen. Als je bovenstaande kan gebruiken weet je genoeg.
Sla onderstaande script op als Model.php en plaats in je root directory
<?php class Model { //Private parameters zijn kan je alleen binnen het object gebruiken private $query_log = []; private $query = ''; private $bind_params = []; private $limit = ''; private $where = []; private $original = []; //deze kan je overschrijven in je child class protected $table = ''; protected $primaryKey = 'id'; //ophalen van één object dmv de primaire sleutel public function find($id): self { $db = new Database(); $this->setQuery("SELECT * FROM {$this->getTable()} WHERE `{$this->primaryKey}` = ?"); $this->original = $db->query($this->query, [$id])->fetch(); if ($this->original) { foreach ($this->original as $k => $v) { $this->$k = $v; } } else { echo "id=$id not found"; die(); } return $this; } //Object opslaan in de database public function save(): self { if ($this->original[$this->primaryKey]) { $db = new Database(); $update = []; $cols = []; foreach ($this->original as $k => $v) { if ($this->$k != $v) { $cols[] = "`$k` = ?"; $update[] = $this->$k; } } if (!empty($cols)) { $update[] = $this->original[$this->primaryKey]; $this->setQuery("UPDATE {$this->getTable()} SET " . implode(",", $cols) . " WHERE `{$this->primaryKey}`=?" ); $db->query($this->query, $update); $this->find($this->original[$this->primaryKey]); } } return $this; } //nieuw object aanmaken (en opslaan in de database) public function create($array): self { $placeholders = []; $cols = []; $values = []; foreach ($array as $k => $v) { $cols[] = "`" . $k . "`"; $values[] = $v; $placeholders[] = " ?"; } if (!empty($cols)) { $db = new Database(); $this->setQuery("INSERT INTO {$this->getTable()} (" . implode(",", $cols) . ") " . "VALUES (" . implode(",", $placeholders) . ")"); $db->query($this->query, $values); $id = $db->lastInsertId(); $this->find($id); } return $this; } //Object verwijderen public function delete() { if ($this->original[$this->primaryKey]) { $db = new Database(); $this->setQuery("DELETE FROM {$this->getTable()} WHERE `{$this->primaryKey}` = ?"); $db->query($this->query, [$this->original[$this->primaryKey]]); $this->destruct(); } return null; } //alle objecten ophalen public function all() { $db = new Database(); $this->setQuery("SELECT * FROM {$this->getTable()}"); return $db->query($this->query)->fetchAll(); } //bouwen van een query op de betreffende tabel public function where(...$args): self { if (!isset($args[2])) { $value = $args[1]; $operator = "="; } else { $value = $args[2]; $operator = $args[1]; } $this->where[] = ['column' => $args[0], 'value' => $value, 'operator' => $operator]; return $this; } //bouwen van een query op de betreffende tabel public function whereNull($col): self { $this->where[] = ['column' => $col, 'operator' => ' IS NULL']; return $this; } //bouwen van een query op de betreffende tabel public function whereNotNull($col): self { $this->where[] = ['column' => $col, 'operator' => ' IS NOT NULL']; return $this; } public function limit(...$args): self { if (isset($args[1])) { $this->limit = " LIMIT {$args[0]},{$args[1]}"; } else { $this->limit = " LIMIT {$args[0]}"; } return $this; } //Werkelijk uitvoeren van de query public function get(): array { $this->buildQuery(); $db = new Database(); return $db->query($this->query, $this->bind_params)->fetchAll(); } //in plaats van get() kan je deze gebruiken om de querie te dumpen ipv uitvoeren public function dumpQuery(): void { $this->buildQuery(); dd($this->query); } //alle uitgevoerde queries dumpen public function dumpQueryLog(): void { dd($this->query_log); } //niets mee doen protected function getTable(): string { return $this->table ?? rtrim(strtolower(get_class($this)), "s"); } //om een query log op te bouwen (wordt intern gebruikt) private function setQuery($query) { $this->query = $query; $this->query_log[] = $query; } //bouwen van een query aan de hand van where private function buildQuery(): void { $where = []; $this->bind_params = []; foreach ($this->where as $v) { $where[] = "`{$v['column']}` {$v['operator']}" . (isset($v['value']) ? ' ?' : ''); if ($v['value'] ?? null) { $this->bind_params[] = $v['value']; } } $this->setQuery("SELECT * FROM {$this->getTable()} " . (!empty($where) ? ' WHERE ' . implode(" AND ", $where) : '') . $this->limit ); } //object leegmaken private function destruct(): void { foreach ($this->original as $k => $v) { unset($this->$k); } $this->original = []; } }