Przerzucamy metody z klasy pochodnej do klasy bazowej. Rozbudowa naszego projektu MVC. Do dzieła.
Najpierw rzućmy okiem na klasy z poprzedniej lekcji:
abstract class Model {
protected static $conn;
public static function setConn($conn)
{
static::$conn = $conn;
}
public static function keysString(){
return "(" . implode(", ", static::$keys) . ")";
}
public static function valuesString(){
$values = array_map(fn($k) => ":$k", static::$keys);
return "(" . implode(", ", $values) . ")";
}
abstract public static function insert($data);
}
class PersonModel extends Model {
protected static $tablename = 'people';
protected static $keys = ['name', 'age'];
public static function insert($data){
$table = self::$tablename;
$keys = static::keysString();
$vals = static::valuesString();
$query = "INSERT INTO {$table} {$keys} VALUES {$vals}";
$stmt = static::$conn->prepare($query);
return $stmt->execute($data);
}
public static function all($type=PDO::FETCH_OBJ){
$table = self::$tablename;
$query = "SELECT * FROM $table";
$stmt = static::$conn->prepare($query);
$stmt->execute();
return $stmt->fetchAll($type);
}
}
Czy przy każdym modelu chcemy implementować insert i all? Jeżeli nie, przenosimy to do klasy bazowej:
abstract class Model {
protected static $conn;
public static function setConn($conn)
{
static::$conn = $conn;
}
public static function keysString(){
return "(" . implode(", ", static::$keys) . ")";
}
public static function valuesString(){
$values = array_map(fn($k) => ":$k", static::$keys);
return "(" . implode(", ", $values) . ")";
}
public static function insert($data){
$table = static::$tablename;
$keys = static::keysString();
$vals = static::valuesString();
$query = "INSERT INTO {$table} {$keys} VALUES {$vals}";
$stmt = static::$conn->prepare($query);
return $stmt->execute($data);
}
public static function all($type=PDO::FETCH_OBJ){
$table = static::$tablename;
$query = "SELECT * FROM $table";
$stmt = static::$conn->prepare($query);
$stmt->execute();
return $stmt->fetchAll($type);
}
}
class PersonModel extends Model {
protected static $tablename = 'people';
protected static $keys = ['name', 'age'];
}
Musieliśmy zamienić self na static – klasa Model nie posiada pola tablename ani keys. Self było dobre, gdy trzymaliśmy te metody w PersonModel, ale to się skończyło.
Mamy natomiast już 2 metody, które do działania potrzebują tylko podania w klasie pochodnej odpowiedniej nazwy tabeli oraz kluczy.
W Laravelu to jest jeszcze łatwiejsze, bo nazwa tabeli jest dedukowana po nazwie modelu, ale w Laravelu jest więcej warstw abstrakcji i trochę nam zajmie czasu, zanim ten poziom osiągniemy.