ORM клас на PHP

Php’de veritabanı işlemleri için PDO kullanarak kendi ORM sınıfımızı yazalım. Bu sınıf sayesinde veri tabanında kayıt ekleme, silme, güncelleme ve listeleme özelliklerini çok kolay bir şekilde gerçekleştiebiliriz.

 null,  
 'offset' => null,  
 'orderby' => null,  
 ];  

 public function __construct(array $config = [])  
 {  
 try {  
 $type = strtolower($config['type'] ?? 'mysql');  

 switch ($type) {  
 case 'mysql':  
 $dsn = sprintf(  
 "mysql:host=%s;dbname=%s;charset=utf8mb4",  
 $config['host'] ?? 'localhost',  
 $config['database']  
 );  
 $this->pdo = new \PDO(  
 $dsn,  
 $config['username'] ?? 'root',  
 $config['password'] ?? '',  
 $config['options'] ?? []  
 );  
 break;  
 case 'sqlite':  
 $dsn = "sqlite:" . $config['database'];  
 $this->pdo = new \PDO($dsn);  
 break;  
 default:  
 throw new \InvalidArgumentException("Desteklenmeyen veritabanı tipi: $type");  
 }  
 $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);  

 } catch (\PDOException $e) {  
 throw new \RuntimeException("Veritabanı bağlantısı başarısız: " . $e->getMessage());  
 }  
 }  

 public function table($tableName)  
 {  
 $this->table = $tableName;  
 $this->resetQueryParams();  
 return $this;  
 }  

 public function insert(array $data, ?array $columns = null): bool  
 {  
 // Eğer sıralı dizi ve kolonlar belirtilmişse  
 if ($columns !== null && array_keys($data) === range(0, count($data) - 1)) {  
 if (count($columns) !== count($data)) {  
 throw new \InvalidArgumentException('Kolon sayısı ile veri sayısı eşleşmiyor.');  
 }  

 // Sıralı diziyi anahtarlı diziye çevir  
 $data = array_combine($columns, $data);  
 }  

 // Kolonları ve placeholder'ları hazırla  
 $columns = implode(', ', array_keys($data));  
 $placeholders = ':' . implode(', :', array_keys($data));  

 // SQL sorgusunu oluştur  
 $sql = "INSERT INTO {$this->table} ($columns) VALUES ($placeholders)";  

 // Sorguyu hazırla ve çalıştır  
 $stmt = $this->pdo->prepare($sql);  
 return $stmt->execute($data);  
 }  

 #Çoklu veri ekleme  
 public function insertMulti($table, array $columns, array $data)  
 {  
 try {  
 // Kolon isimlerini virgülle ayırarak al  
 $columnString = implode(', ', $columns);  

 // Yer tutucuları oluştur  
 $placeholders = '(' . implode(', ', array_fill(0, count($columns), '?')) . ')';  

 // Yer tutucuları çoğalt (her veri seti için)  
 $placeholderString = implode(', ', array_fill(0, count($data), $placeholders));  

 // Sorguyu oluştur  
 $query = "INSERT INTO {$table} ({$columnString}) VALUES {$placeholderString}";  

 // Sorguyu hazırla  
 $stmt = $this->pdo->prepare($query);  

 // Veriyi düzleştir ve sırala  
 $flattenedData = [];  
 foreach ($data as $row) {  
 if (is_array($row)) {  
 // Eğer anahtarlı dizi ise, kolonlara göre sırala  
 if (array_keys($row) !== range(0, count($row) - 1)) {  
 $orderedRow = [];  
 foreach ($columns as $column) {  
 $orderedRow[] = $row[$column] ?? null;  
 }  
 $flattenedData = array_merge($flattenedData, $orderedRow);  
 } else {  
 // Sıralı dizi ise direkt ekle  
 $flattenedData = array_merge($flattenedData, $row);  
 }  
 }  
 }  

 // Sorguyu çalıştır  
 return $stmt->execute($flattenedData);  
 } catch (\PDOException $e) {  
 throw new \Exception("Veri ekleme hatası: " .  

$e->getMessage());  
 }  
 }  

 public function read($columns = '*')  
 {  
 if (is_array($columns)) {  
 $columns = implode(', ', array_map([$this->pdo, 'quote'], $columns));  
 }  

 $sql = "SELECT $columns FROM {$this->table}";  
 $params = [];  

 if (!empty($this->conditions)) {  
 $whereClauses = [];  
 foreach ($this->conditions as $key => $value) {  
 if (is_array($value) && isset($value['operator'])) {  
 switch ($value['operator']) {  
 case 'LIKE':  
 $whereClauses[] = "$key LIKE :$key";  
 $params[$key] = $value['value'];  
 break;  
 case 'IN':  
 $inParams = [];  
 foreach ($value['value'] as $i => $val) {  
 $paramKey = "{$key}_{$i}";  
 $inParams[] = ":{$paramKey}";  
 $params[$paramKey] = $val;  
 }  
 $whereClauses[] = "$key IN (" . implode(', ', $inParams) . ")";  
 break;  
 case 'BETWEEN':  
 $whereClauses[] = "$key BETWEEN :{$key}_start AND :{$key}_end";  
 $params["{$key}_start"] = $value['value'][0];  
 $params["{$key}_end"] = $value['value'][1];  
 break;  
 case '>':  
 case '<':  
 case '>=':  
 case '<=':  
 case '<>':  
 case '!=':  
 case '=':  
 $whereClauses[] = "$key {$value['operator']} :$key";  
 $params[$key] = $value['value'];  
 break;  
 }  
 } else {  
 $whereClauses[] = "$key = :$key";  
 $params[$key] = $value;  
 }  
 }  
 $sql .= ' WHERE ' . implode(' AND ', $whereClauses);  
 }  

 if (!empty($this->queryParams['orderby'])) {  
 $sql .= ' ORDER BY ' . $this->queryParams['orderby'];  
 }  

 if (!empty($this->queryParams['limit'])) {  
 $sql .= ' LIMIT ' . $this->queryParams['limit'];  
 }  

 if (!empty($this->queryParams['offset'])) {  
 $sql .= ' OFFSET ' . $this->queryParams['offset'];  
 }  

 $stmt = $this->pdo->prepare($sql);  
 $stmt->execute($params);  

 $this->resetQueryParams();  

 return $stmt->fetchAll(\PDO::FETCH_ASSOC);  
 }  

 public function update(array $data)  
 {  
 $setClauses = [];  
 $params = [];  

 foreach ($data as $key => $value) {  
 $setClauses[] = "$key = :set_$key";  
 $params["set_$key"] = $value;  
 }  

 $sql = "UPDATE {$this->table} SET " . implode(', ', $setClauses);  

 if (!empty($this->conditions)) {  
 $whereClauses = [];  
 foreach ($this->conditions as $key => $value) {  
 if (is_array($value) && isset($value['operator'])) {  
 switch ($value['operator']) {  
 case 'LIKE':  
 $whereClauses[] = "$key LIKE :where_$key";  
 $params["where_$key"] = $value['value'];  
 break;  
 case '>':  
 case '<':  
 case '>=':  
 case '<=':  
 case '<>':  
 case '!=':  
 case '=':  
 $whereClauses[] = "$key {$value['operator']} :where_$key";  
 $params["where_$key"] = $value['value'];  
 break;  
 }  
 } else {  
 $whereClauses[] = "$key = :where_$key";  
 $params["where_$key"] = $value;  
 }  
 }  
 $sql .= ' WHERE ' . implode(' AND ', $whereClauses);  
 }  

 $stmt = $this->pdo->prepare($sql);  
 $result = $stmt->execute($params);  

 $this->resetQueryParams();  

 return $result;  
 }  

 public function delete()  
 {  
 $sql = "DELETE FROM {$this->table}";  
 $params = [];  

 if (!empty($this->conditions)) {  
 $whereClauses = [];  
 foreach ($this->conditions as $key => $value) {  
 if (is_array($value) && isset($value['operator'])) {  
 switch ($value['operator']) {  
 case 'LIKE':  
 $whereClauses[] = "$key LIKE :$key";  
 $params[$key] = $value['value'];  
 break;  
 case '>':  
 case '<':  
 case '>=':  
 case '<=':  
 case '<>':  
 case '!=':  
 case '=':  
 $whereClauses[] = "$key {$value['operator']} :$key";  
 $params[$key] = $value['value'];  
 break;  
 }  
 } else {  
 $whereClauses[] = "$key = :$key";  
 $params[$key] = $value;  
 }  
 }  
 $sql .= ' WHERE ' .  

implode(' AND ', $whereClauses);  
 }  

 $stmt = $this->pdo->prepare($sql);  
 $result = $stmt->execute($params);  

 $this->resetQueryParams();  

 return $result;  
 }  

 public function where($column, $operator, $value)  
 {  
 $validOperators = ['>', '<', '>=', '<=', '<>', '!=', '='];  

 if (!in_array($operator, $validOperators)) {  
 throw new \InvalidArgumentException("Невірний оператор: $operator");  
 }  

 $this->conditions[$column] = [  
 'operator' => $operator,  
 'value' => $value  
 ];  

 return $this;  
 }  

 public function like($column, $value)  
 {  
 $this->conditions[$column] = [  
 'operator' => 'LIKE',  
 'value' => $value  
 ];  
 return $this;  
 }  

 public function between($column, $start, $end)  
 {  
 $this->conditions[$column] = [  
 'operator' => 'BETWEEN',  
 'value' => [$start, $end]  
 ];  
 return $this;  
 }  

 public function in($column, array $values)  
 {  
 $this->conditions[$column] = [  
 'operator' => 'IN',  
 'value' => $values  
 ];  
 return $this;  
 }  

 public function limit($limit)  
 {  
 $this->queryParams['limit'] = (int)$limit;  
 return $this;  
 }  

 public function offset($offset)  
 {  
 $this->queryParams['offset'] = (int)$offset;  
 return $this;  
 }  

 public function orderBy($column, $direction = 'ASC')  
 {  
 $direction = strtoupper($direction);  
 if (!in_array($direction, ['ASC', 'DESC'])) {  
 throw new \InvalidArgumentException("Невірний напрямок сортування: $direction");  
 }  
 $this->queryParams['orderby'] = "$column $direction";  
 return $this;  
 }  
 public function sql($query)  
 {  
 try {  
 return $this->pdo->exec($query); // Виконати запит  
 } catch (\PDOException $e) {  
 throw new \Exception("SQL помилка: " . $e->getMessage());  
 }  
 }  

 private function resetQueryParams()  
 {  
 $this->queryParams = [  
 'limit' => null,  
 'offset' => null,  
 'orderby' => null,  
 ];  
 $this->conditions = [];  
 }  

 public function beginTransaction()  
 {  
 return $this->pdo->beginTransaction();  
 }  

 public function commit()  
 {  
 return $this->pdo->commit();  
 }  

 public function rollBack()  
 {  
 return $this->pdo->rollBack();  
 }  
}

Ось як можна використовувати всі CRUD (Create, Read, Update, Delete) операції класу з прикладами:

1. Додавання даних (Create)

$config = [  
 'type' => 'mysql', // Тип бази даних: 'mysql' або 'sqlite'  
 'host' => 'localhost', // Хост для MySQL  
 'database' => 'test_db', // Назва бази даних  
 'username' => 'root', // Ім'я користувача  
 'password' => '', // Пароль  
 'options' => [ // Опції підключення PDO (необов'язково)  
 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,  
 ],  
];  

$orm = new Orm($config);  
// Вибір таблиці та додавання даних  
$result = $orm->table('users')->insert([  
'name' => 'John Doe',  
'email' => '[email protected]',  
'age' => 25  
]);  
if ($result) {  
echo "Дані успішно додано!";  
} else {  
echo "Сталася помилка під час додавання даних.";  
}

2. Читання даних (Read)

a. Читання всіх даних

$users = $orm->table('users')->read();  
foreach ($users as $user) {  
echo "Ім'я: {$user['name']}, Електронна пошта: {$user['email']}, Вік: {$user['age']}";  
}

b. Читання даних з умовами

$users = $orm->table('users')->read(['age' => 25]);  
foreach ($users as $user) {  
echo "Ім'я: {$user['name']}, Електронна пошта: {$user['email']}, Вік: {$user['age']}";  
}  
c. Читання обмежених та відсортованих даних  
$users = $orm->table('users')  
->orderby('age', 'DESC')  
->limit(5)  
->offset(0)  
->read();  
foreach ($users as $user) {  
echo "Ім'я: {$user['name']}, Електронна пошта: {$user['email']}, Вік: {$user['age']}";  
}

3. Оновлення даних (Update)

$result = $orm->table('users')->update(  
['name' => 'Jane Doe', 'age' => 30], // Оновлені дані  
['email' => '[email protected]'] // Умови  
);  
if ($result) {  
echo "Дані успішно оновлено!";  
} else {  
echo "Сталася помилка під час оновлення даних.";  
}

Видалення даних (Delete)

$result = $orm->table('users')->delete(['email' => '[email protected]']);
if ($result) {
echo "Дані успішно видалено!";
} else {
echo "Сталася помилка під час видалення даних.";
}
```

Підсумок CRUD-операцій

Create: додайте дані за допомогою create().

Read: отримуйте дані за допомогою read(); за потреби додавайте умови, сортування, ліміти та offset.

Update: оновлюйте дані за допомогою update() відповідно до заданих умов.

Delete: видаляйте дані за допомогою delete() відповідно до умов.

Це дуже допомогло мені. Можливо, це стане в нагоді й іншим. Удачі!

Перекладено з: Php ile ORM Sınıfı

Leave a Reply

Your email address will not be published. Required fields are marked *