1: <?php
2:
3: namespace nightmare\database;
4:
5: use PDO;
6: use PDOStatement;
7:
8: class database
9: {
10: /**
11: * @var PDO
12: */
13: private $driver;
14:
15: public function __construct(
16: $dsn,
17: $username = null,
18: $password = null,
19: $options = null
20: ) {
21: if ($dsn instanceof PDO) {
22: $this->driver = $dsn;
23: } else {
24: $this->driver = new PDO(
25: $dsn,
26: $username,
27: $password,
28: array_merge([
29: PDO::MYSQL_ATTR_INIT_COMMAND, 'SET sql_mode="ANSI,TRADITIONAL"'
30: ], (array) $options)
31: );
32: }
33:
34: $this->driver->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
35: $this->driver->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
36: $this->driver->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_CLASS);
37: $this->driver->setAttribute(PDO::ATTR_STATEMENT_CLASS, [statement::class]);
38:
39: $this->driver->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
40: }
41:
42: public function driver()
43: {
44: return $this->driver;
45: }
46:
47: public function get_pdo()
48: {
49: return $this->driver;
50: }
51:
52: /**
53: * @param string $sql
54: * @param array|null $params
55: * @return PDOStatement|false
56: */
57: public function query($sql, $params = null)
58: {
59: $stmt = $this->driver->prepare($sql);
60: $stmt->execute($params);
61:
62: return $stmt;
63: }
64:
65: /**
66: * giống exec() nhưng dùng prepare
67: *
68: * @param string $sql
69: * @param array|null $params
70: * @return int
71: */
72: public function query_count($sql, $params = null)
73: {
74: $stmt = $this->driver->prepare($sql);
75: $stmt->execute($params);
76:
77: return $stmt->rowCount();
78: }
79:
80: /**
81: * @param string $table
82: * @param array $params
83: * @return string
84: */
85: public function insert($table, $params)
86: {
87: $sql = 'insert into "' . $table . '"'
88: . ' (' . implode(',', $this->buildName(array_keys($params))) . ')'
89: . ' values (' . implode(',', array_fill(0, count($params), '?')) . ')';
90: //dd($sql);
91: $this->query($sql, array_values($params));
92:
93: return $this->driver->lastInsertId();
94: }
95:
96: /**
97: * @param string $table
98: * @param array $con
99: * @param array $arr
100: * @return void
101: */
102: public function update_or_insert($table, $con, $arr)
103: {
104: $where_conditions = [];
105: $where_params = [];
106:
107: foreach ($con as $column => $value) {
108: $where_conditions[] = sprintf('"%s" = ?', $column);
109: $where_params[] = $value;
110: }
111:
112: $where_clause = implode(' AND ', $where_conditions);
113: $check_sql = sprintf('SELECT COUNT(*) FROM "%s" WHERE %s', $table, $where_clause);
114: $count = $this->fetch_column($check_sql, $where_params);
115:
116: if ($count > 0) {
117: $update_parts = [];
118: $update_params = [];
119:
120: foreach ($arr as $column => $value) {
121: $update_parts[] = sprintf('"%s" = ?', $column);
122: $update_params[] = $value;
123: }
124:
125: $update_clause = implode(', ', $update_parts);
126: $update_sql = sprintf('UPDATE "%s" SET %s WHERE %s', $table, $update_clause, $where_clause);
127:
128: $this->query($update_sql, array_merge($update_params, $where_params));
129: } else {
130: $this->insert($table, array_merge($con, $arr));
131: }
132: }
133:
134: /**
135: * @param string $sql
136: * @param array|null $params
137: * @return int
138: */
139: public function update($sql, $params = null)
140: {
141: $stmt = $this->query($sql, $params);
142: return $stmt->rowCount();
143: }
144:
145: /**
146: * @param string $sql
147: * @param array|null $params
148: * @return mixed
149: */
150: public function fetch($sql, $params = null)
151: {
152: return $this->query($sql, $params)->fetch();
153: }
154:
155: public function exec($sql)
156: {
157: return $this->driver->exec($sql);
158: }
159:
160: /**
161: * @param string $sql
162: * @param array|null $params
163: * @return array
164: */
165: public function fetchAll($sql, $params = null)
166: {
167: return $this->query($sql, $params)->fetchAll();
168: }
169:
170: /**
171: * @param string $sql
172: * @param array|null $params
173: * @return array
174: */
175: public function fetch_all($sql, $params = null)
176: {
177: return $this->query($sql, $params)->fetchAll();
178: }
179:
180: /**
181: * @param string $sql
182: * @param array|null $params
183: * @param int $column
184: * @return mixed
185: */
186: public function fetchColumn($sql, $params = null, $column = 0)
187: {
188: $stmt = $this->query($sql, $params);
189: return $stmt->fetchColumn($column);
190: }
191:
192: /**
193: * @param string $sql
194: * @param array|null $params
195: * @param int $column
196: * @return mixed
197: */
198: public function fetch_column($sql, $params = null, $column = 0)
199: {
200: $stmt = $this->query($sql, $params);
201: return $stmt->fetchColumn($column);
202: }
203:
204: /**
205: * @param int $page
206: * @param int $per_page
207: * @return int
208: */
209: public function getOffset($page, $per_page)
210: {
211: return $page * $per_page - $per_page;
212: }
213:
214: /**
215: * @param int $page
216: * @param int $per_page
217: * @return int
218: */
219: public function get_offset($page, $per_page)
220: {
221: return $page * $per_page - $per_page;
222: }
223:
224: /**
225: * @param string $str
226: * @return string
227: */
228: public function quote($str)
229: {
230: return $this->driver->quote($str);
231: }
232:
233: /**
234: * @param array $arr
235: * @return array
236: */
237: public function buildName($arr)
238: {
239: return array_map(function ($item) {
240: return '"' . $item . '"';
241: }, $arr);
242: }
243:
244: /**
245: * @param array $arr
246: * @return array
247: */
248: public function build_name($arr)
249: {
250: return array_map(function ($item) {
251: return '"' . $item . '"';
252: }, $arr);
253: }
254: }
255: