160 lines
4.4 KiB
PHP
160 lines
4.4 KiB
PHP
<?php
|
||
|
||
namespace App\Core;
|
||
|
||
abstract class Model
|
||
{
|
||
protected Database $db;
|
||
protected string $table = '';
|
||
protected string $primaryKey = 'id';
|
||
|
||
public function __construct()
|
||
{
|
||
$this->db = Database::getInstance();
|
||
}
|
||
|
||
public function find(int $id): ?array
|
||
{
|
||
$sql = "SELECT * FROM {$this->table} WHERE {$this->primaryKey} = ?";
|
||
return $this->db->queryOne($sql, [$id]);
|
||
}
|
||
|
||
public function all(?string $orderBy = null): array
|
||
{
|
||
$sql = "SELECT * FROM {$this->table}";
|
||
if ($orderBy) {
|
||
$sql .= " ORDER BY {$orderBy}";
|
||
}
|
||
return $this->db->query($sql);
|
||
}
|
||
|
||
public function where(array $conditions, ?string $orderBy = null): array
|
||
{
|
||
$where = [];
|
||
$params = [];
|
||
|
||
foreach ($conditions as $column => $value) {
|
||
$where[] = "{$column} = ?";
|
||
$params[] = $value;
|
||
}
|
||
|
||
$sql = "SELECT * FROM {$this->table} WHERE " . implode(' AND ', $where);
|
||
|
||
if ($orderBy) {
|
||
$sql .= " ORDER BY {$orderBy}";
|
||
}
|
||
|
||
return $this->db->query($sql, $params);
|
||
}
|
||
|
||
public function findWhere(array $conditions): ?array
|
||
{
|
||
$where = [];
|
||
$params = [];
|
||
|
||
foreach ($conditions as $column => $value) {
|
||
$where[] = "{$column} = ?";
|
||
$params[] = $value;
|
||
}
|
||
|
||
$sql = "SELECT * FROM {$this->table} WHERE " . implode(' AND ', $where) . " LIMIT 1";
|
||
return $this->db->queryOne($sql, $params);
|
||
}
|
||
|
||
public function create(array $data): ?int
|
||
{
|
||
$columns = array_keys($data);
|
||
$placeholders = array_fill(0, count($data), '?');
|
||
|
||
$sql = sprintf(
|
||
"INSERT INTO %s (%s) VALUES (%s) RETURNING %s",
|
||
$this->table,
|
||
implode(', ', $columns),
|
||
implode(', ', $placeholders),
|
||
$this->primaryKey
|
||
);
|
||
|
||
$stmt = $this->db->getConnection()->prepare($sql);
|
||
|
||
// Правильно биндим параметры с учетом типов
|
||
$params = array_values($data);
|
||
foreach ($params as $index => $param) {
|
||
$paramNum = $index + 1;
|
||
if (is_bool($param)) {
|
||
$stmt->bindValue($paramNum, $param, \PDO::PARAM_BOOL);
|
||
} elseif (is_int($param)) {
|
||
$stmt->bindValue($paramNum, $param, \PDO::PARAM_INT);
|
||
} elseif (is_null($param)) {
|
||
$stmt->bindValue($paramNum, $param, \PDO::PARAM_NULL);
|
||
} else {
|
||
$stmt->bindValue($paramNum, $param, \PDO::PARAM_STR);
|
||
}
|
||
}
|
||
|
||
$stmt->execute();
|
||
|
||
return (int) $stmt->fetchColumn();
|
||
}
|
||
|
||
public function update(int $id, array $data): bool
|
||
{
|
||
$set = [];
|
||
$params = [];
|
||
|
||
foreach ($data as $column => $value) {
|
||
$set[] = "{$column} = ?";
|
||
$params[] = $value;
|
||
}
|
||
$params[] = $id;
|
||
|
||
$sql = sprintf(
|
||
"UPDATE %s SET %s WHERE %s = ?",
|
||
$this->table,
|
||
implode(', ', $set),
|
||
$this->primaryKey
|
||
);
|
||
|
||
return $this->db->execute($sql, $params);
|
||
}
|
||
|
||
public function delete(int $id): bool
|
||
{
|
||
$sql = "DELETE FROM {$this->table} WHERE {$this->primaryKey} = ?";
|
||
return $this->db->execute($sql, [$id]);
|
||
}
|
||
|
||
public function count(array $conditions = []): int
|
||
{
|
||
$sql = "SELECT COUNT(*) FROM {$this->table}";
|
||
$params = [];
|
||
|
||
if (!empty($conditions)) {
|
||
$where = [];
|
||
foreach ($conditions as $column => $value) {
|
||
$where[] = "{$column} = ?";
|
||
$params[] = $value;
|
||
}
|
||
$sql .= " WHERE " . implode(' AND ', $where);
|
||
}
|
||
|
||
$stmt = $this->db->getConnection()->prepare($sql);
|
||
$stmt->execute($params);
|
||
return (int) $stmt->fetchColumn();
|
||
}
|
||
|
||
protected function query(string $sql, array $params = []): array
|
||
{
|
||
return $this->db->query($sql, $params);
|
||
}
|
||
|
||
protected function queryOne(string $sql, array $params = []): ?array
|
||
{
|
||
return $this->db->queryOne($sql, $params);
|
||
}
|
||
|
||
protected function execute(string $sql, array $params = []): bool
|
||
{
|
||
return $this->db->execute($sql, $params);
|
||
}
|
||
}
|