139 lines
4.0 KiB
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;
|
|
}
|
|
}
|