Nie bawimy się w Repository Pattern – zamiast tego tworzymy model przypominający te z Laravela tak, jak to tylko możliwe. Do dzieła.
Nasz model wygląda tak:
class PersonModel extends Model {
protected static $tablename = 'people';
protected static $keys = ['name', 'age'];
}
I tyle konfiguracji ma wystarczyć. Reszta w klasie bazowej. Chcemy osiągnąć coś takiego:
$person = new PersonModel();
$person->setConn($conn);
$person->name = "Jim";
$person->age = 22;
echo $person->name . " " . $person->age;
$person->save(); //INSERT INTO DB
$person->age = 29;
$person->save(); //UPDATE
Dodajemy nowe pola w klasie bazowej:
abstract class Model {
public $id;
private $data = array();
protected static $conn;
const OPERATORS = ['=', '>=', '>', '<=', '<', '<>'];
//(...)
}
Teraz konstruktor:
abstract class Model {
//(...)
public function __construct()
{
$this->id = null;
}
}
Metody get i set:
abstract class Model {
//(...)
public function __set($name, $value) {
$this->data[$name] = $value;
}
public function __get($name){
if(array_key_exists($name, $this->data))
return $this->data[$name];
}
}
Już teraz możemy wykonać tę część:
$person = new PersonModel();
$person->setConn($conn);
$person->name = "Jim";
$person->age = 22;
echo $person->name . " " . $person->age;
Metoda save wygląda tak:
abstract class Model {
//(...)
public function save(){
$data = $this->data;
if(is_null($this->id)){
//INSERT INTO table ....
} else {
//UPDATE table SET key = 'val', key2 = 'val2' WHERE id = $this->id
}
}
}
Piszemy część robiącą insert podobnie jak w statycznej metodzie insert:
abstract class Model {
//(...)
public function save(){
$data = $this->data;
if(is_null($this->id)){
$table = static::$tablename;
$keys = static::keysString();
$vals = static::valuesString();
$query = "INSERT INTO {$table} {$keys} VALUES {$vals}";
$stmt = static::$conn->prepare($query);
$stmt->execute($data);
$this->id = static::$conn->lastInsertId();
} else {
//UPDATE table SET key = 'val', key2 = 'val2' WHERE id = $this->id
}
}
}
Podobnie z UPDATE – logika może i trochę pokręcona, ale możemy to sobie zdebugować:
abstract class Model {
//(...)
public function save(){
$data = $this->data;
if(is_null($this->id)){
//insert to id
//assign $this->id to lastInsertedId
} else {
$table = static::$tablename;
$setSTR = "";
foreach($data as $key => $value){
$setSTR .= $key;
$setSTR .= " = ";
$setSTR .= '"'.$value.'"';
if($key === array_key_last($data))
break;
$setSTR .= ", ";
}
$query = "UPDATE {$table} SET {$setSTR} WHERE id = {$this->id}";
$stmt = static::$conn->prepare($query);
$stmt->execute();
}
}
}
Teraz bez problemu możemy zapisywać robiąc zarówno insert jak i update:
$person->name = "Jim";
$person->age = 22;
echo $person->name . " " . $person->age;
$person->save();
$person->age = 29;
$person->save();