CrestRoad/website/includes/mysqli-class.php

139 lines
4.0 KiB
PHP

<?php
class MysqliDb
{
/** @var mysqli */
private $conn;
public function __construct(array $config)
{
$host = $config['host'] ?? '127.0.0.1';
$user = $config['username'] ?? 'root';
$pass = $config['password'] ?? '';
$db = $config['db'] ?? '';
$port = $config['port'] ?? null;
$socket = $config['socket'] ?? null;
$charset = $config['charset'] ?? 'utf8mb4';
$this->conn = @new mysqli($host, $user, $pass, $db, $port ?? ini_get("mysqli.default_port"), $socket);
if ($this->conn->connect_errno) {
throw new Exception('MySQL connection error: ' . $this->conn->connect_error);
}
$this->conn->set_charset($charset);
}
/**
* @return array|bool
*/
public function rawQuery(string $sql, array $params = [])
{
if (empty($params)) {
$result = $this->conn->query($sql);
if ($result === false) {
throw new Exception('Query error: ' . $this->conn->error);
}
if ($result === true) {
return true;
}
$data = $result->fetch_all(MYSQLI_ASSOC);
$result->free();
return $data;
}
$stmt = $this->prepareAndBind($sql, $params);
if (!$stmt->execute()) {
throw new Exception('Query error: ' . $stmt->error);
}
$res = $stmt->get_result();
$rows = $res ? $res->fetch_all(MYSQLI_ASSOC) : [];
$stmt->close();
return $rows;
}
/**
* @return array|bool
*/
public function query(string $sql, array $params = [])
{
return $this->rawQuery($sql, $params);
}
/**
* @return array|null
*/
public function getOne(string $sql, array $params = [])
{
$rows = $this->rawQuery($sql, $params);
return $rows[0] ?? null;
}
public function getValue(string $sql, array $params = [])
{
$row = $this->getOne($sql, $params);
if (!$row) {
return null;
}
return array_shift($row);
}
public function insert(string $table, array $data): int
{
$cols = array_keys($data);
$placeholders = implode(',', array_fill(0, count($cols), '?'));
$colList = '`' . implode('`,`', $cols) . '`';
$sql = "INSERT INTO `$table` ($colList) VALUES ($placeholders)";
$stmt = $this->prepareAndBind($sql, array_values($data));
if (!$stmt->execute()) {
throw new Exception('Insert error: ' . $stmt->error);
}
$id = $stmt->insert_id ?: $this->conn->insert_id;
$stmt->close();
return (int) $id;
}
public function deleteById(string $table, int $id): bool
{
$stmt = $this->prepareAndBind("DELETE FROM `$table` WHERE id = ?", [$id]);
$ok = $stmt->execute();
$stmt->close();
return $ok;
}
public function update(string $table, array $data, string $where, array $params = []): bool
{
$sets = [];
$values = [];
foreach ($data as $col => $val) {
$sets[] = "`$col` = ?";
$values[] = $val;
}
$sql = "UPDATE `$table` SET " . implode(',', $sets) . " WHERE $where";
$bind = array_merge($values, $params);
$stmt = $this->prepareAndBind($sql, $bind);
$ok = $stmt->execute();
$stmt->close();
return $ok;
}
private function prepareAndBind(string $sql, array $params): mysqli_stmt
{
$stmt = $this->conn->prepare($sql);
if (!$stmt) {
throw new Exception('Prepare failed: ' . $this->conn->error);
}
if (!empty($params)) {
$types = '';
$refs = [];
foreach ($params as $param) {
$types .= is_int($param) ? 'i' : (is_float($param) ? 'd' : 's');
}
$refs[] = &$types;
foreach ($params as $k => $v) {
$refs[] = &$params[$k];
}
$stmt->bind_param(...$refs);
}
return $stmt;
}
}