146 lines
4.6 KiB
PHP
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
|