MVC/lib/Core/Model.php
2024-08-23 14:41:51 +09:00

146 lines
4.6 KiB
PHP

<?php
namespace lib\Core;
use Exception;
use PDO;
use PDOException;
use PDOStatement;
abstract class Model
{
private $_db = null;
private $_wheres = [];
private $_primaryKey = false;
protected $resultMode = 'array';
protected function __construct(string $primaryKey)
{
$this->_primaryKey = $primaryKey;
} //
abstract public function getTable();
final public function getPrimaryKey(): string
{
if (!$this->_primaryKey) {
throw new \Exception("PrimayKey가 지정되지 않았습니다.");
}
return $this->_primaryKey;
}
final public function getDB()
{
if ($this->_db === null) {
$envs = parse_ini_file(APP . DIRECTORY_SEPARATOR . ".env.ini", true);
if (!$envs) {
throw new Exception(var_export($envs, true));
}
$this->_db = new PDO($envs['db']['dsn'], $envs['db']['id'], $envs['db']['passwd']);
// $this->_db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$this->_db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// echo "Connected successfully: " . $this->_db->getAttribute(PDO::ATTR_CONNECTION_STATUS) . "\n";
}
return $this->_db;
}
final public function where($key, $value, $condition = "AND")
{
if (is_array($value)) {
throw new \Exception("Value is Array:" . var_export($value, true));
}
$this->_wheres[] = sprintf(
" %s {$key}=%s",
count($this->_wheres) ? $condition : "WHERE",
is_int($value) ? $value : "'{$value}'"
);
}
private function chanegValueToSQLTypeValue($value)
{
return is_int($value) ? $value : "'{$value}'";
}
final public function execute($sql): bool|PDOStatement
{
$sql .= implode(" ", $this->_wheres);
//echo $sql . "\n";
$stmt = $this->getDB()->prepare($sql);
if (!$stmt->execute()) {
throw new Exception("SQL 오류: {$stmt->errorInfo()} \n{$sql}\n");
}
$this->_wheres = [];
return $stmt;
}
//SQL문
final public function select(array $columns = ["*"]): bool|PDOStatement
{
$sql = sprintf("SELECT %s FROM %s", implode(",", $columns), $this->getTable());
return $this->execute($sql);
}
final public function insert(array $datas)
{
$sqlDatas = [];
foreach ($datas as $key => $value) {
$sqlDatas[$key] = $this->chanegValueToSQLTypeValue($value);
}
$sql = sprintf("INSERT INTO {$this->getTable()} SET (%s) VALUES (%s}", array_keys($sqlDatas), array_values($sqlDatas));
return $this->execute($sql);
}
final public function update(array $datas)
{
$sqlDatas = [];
foreach ($datas as $key => $value) {
if ($key === $this->getPrimaryKey()) { //PrimaryKey변경불가
continue;
}
$value = $this->chanegValueToSQLTypeValue($value);
$sqlDatas[] = "{$key}={$value}";
}
$sql = sprintf("UPDATE {$this->getTable()} SET %s", implode(",", $sqlDatas));
return $this->execute($sql);
}
public function save($entity)
{
if ($entity->isChanged()) {
$pk = $this->getPrimaryKey();
if ($entity->$pk) {
$this->where($pk, $entity->$pk);
$datas = [];
foreach ($entity->getChangedFields() as $key) {
$datas[$key] = $entity->$key;
}
$this->update($datas);
$entity->clearChangedFields();
} else {
$datas = [];
foreach ($entity->getChangedFields() as $key) {
$datas[$key] = $entity->$key;
}
$this->insert($datas);
$entity->$pk = $this->getDB()->lastInsertId();
$entity->clearChangedFields();
}
}
return $entity;
}
final public function getEntity()
{
$stmt = $this->select();
if (class_exists($this->resultMode)) {
$stmt->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, $this->resultMode);
return $stmt->fetch();
}
return $stmt->fetch(PDO::FETCH_DEFAULT);
}
final public function getEntitys()
{
$stmt = $this->select();
if (class_exists($this->resultMode)) {
$stmt->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, $this->resultMode);
return $stmt->fetchAll();
}
return $stmt->fetchAll(PDO::FETCH_DEFAULT);
}
} //Class