-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdb.php
285 lines (210 loc) · 7.14 KB
/
db.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
<?php
/**
* db class to implement singleton pattern on top of mysqli
*/
class db extends mysqli {
/****************************************
* MEMBER VARIABLES *
*****************************************/
// Singleton Instance
private static $mysqli;
/****************************************
* CONSTRUCTOR *
*****************************************/
/**
* Connect to MySQL database
*/
private function __construct() {
// Database Authentication Credentials
$credentials = DBCredentials::get_credentials();
// MySQLi Constructor
@parent::__construct($credentials['host'], $credentials['username'], $credentials['password'], $credentials['database']);
@parent::set_charset('utf8');
// Non-OO technique ensures compatability with some earlier versions of PHP5
if (mysqli_connect_errno()) {
die('Connection Error');
}
}
/****************************************
* SINGLETON INSTANCE *
*****************************************/
/**
* Singleton Design Pattern
*/
public static function get_mysqli() {
// Singleton
if (!isset(self::$mysqli)) {
$class = __CLASS__;
self::$mysqli = new $class();
}
// Return Instance
return self::$mysqli;
}
/****************************************
* EXECUTE *
*****************************************/
public static function execute($sql) {
// Trim Whitespace
$sql = trim($sql);
// Get database instance
$mysqli = self::get_mysqli();
// Execute MySQLi Query
$results = $mysqli->query($sql);
// Successful SQL
if ($results !== FALSE) {
// Create a generic object for results if needed
if (!($results instanceof mysqli_result)) {
$results = (object) NULL;
}
// Add to Results
$results->affected_rows = $mysqli->affected_rows;
$results->insert_id = $mysqli->insert_id;
// Return Results
return $results;
// Failed SQL
} else {
exit('SQL Error: ' . $mysqli->error . "<br><br>" . $sql);
}
}
/****************************************
* INSERTING *
*****************************************/
/**
* Execute Standard INSERT statement
*/
public static function insert($table_name, $sql_values) {
// Make Insert Statement
$sql = self::make_insert_statement($table_name, $sql_values);
// Execute Query
return self::execute($sql);
}
/**
* Execute INSERT statement with ON DUPLICATE KEY UPDATE added
*/
public static function insert_duplicate_key_update($table_name, $sql_values, $ommit_keys = NULL) {
// Make Insert Statement
$sql = self::make_insert_statement($table_name, $sql_values) . "\r\nON DUPLICATE KEY UPDATE " . self::make_sql_update_values($sql_values, $ommit_keys);
// Execute Query
return self::execute($sql);
}
/**
* Execute INSERT IGNORE statement
*/
public static function insert_ignore($table_name, $sql_values) {
// Make Insert Statement
$sql = str_replace('INSERT', 'INSERT IGNORE', self::make_insert_statement($table_name, $sql_values));
// Execute Query
return self::execute($sql);
}
/**
* Create Standard INSERT statement
*/
private static function make_insert_statement($table_name, $sql_values) {
return "INSERT INTO `{$table_name}` (`" . implode('`, `', array_keys($sql_values)) . "`) VALUES (" . implode(', ', $sql_values) . ")";
}
/****************************************
* UPDATING *
*****************************************/
/**
* Execute Standard UPDATE statement
*/
public static function update($table_name, $sql_values, $sql_where) {
// Make Update Statement
$sql = "UPDATE `{$table_name}` SET " . self::make_sql_update_values($sql_values) . ' ' . $sql_where;
// Execute Query
return self::execute($sql);
}
/**
* Create UPDATE key-value pairs
*/
public static function make_sql_update_values($sql_values, $ommit_keys = NULL) {
// Remove Keys with Null Values
$sql_values = array_filter($sql_values);
// Set ommit keys to an array no matter what
$ommit_keys = is_array($ommit_keys) ? $ommit_keys : Array();
// Remove Omitted Keys
$sql_values_light = array_diff_key($sql_values, array_flip($ommit_keys));
// In some cases, ommit keys might eliminate all array entries
// To ensure that this function returns something that can still
// be ran in sql, we set the first value back to itself
if (!count($sql_values_light)) {
reset($sql_values);
return key($sql_values) . ' = ' . key($sql_values);
}
// Loop values to make query string in UPDATE format
foreach ($sql_values_light as $key => $value) {
$sql_array[] .= "`{$key}`={$value}";
}
return implode(',', $sql_array);
}
/****************************************
* UTILITIES *
*****************************************/
/**
* This method wrapps real_escape_string because real_escape_string requires
* a database connection already which might not exist. This funciton
* starts the database connection and then calls real_escape_string.
*/
public static function escape($value) {
$mysqli = self::get_mysqli();
return $mysqli->real_escape_string($value);
}
/**
* Surround a value with single quotes or with the string: 'NULL'
* This function also escapes value and trims white space. The
* $value parameter is pass-by-reference so this function can
* be used as a callback for array_walk.
*/
public static function in_quotes($value) {
// Cast Boolean False
$value = ($value === FALSE) ? '0' : $value;
// Return the word NULL or the value wrapped in quotes
if ($value === '0' || $value === 0 || !empty($value) || (gettype($value) == 'double' && $value == 0)) {
$value = "'" . self::escape(trim($value)) . "'";
} else {
$value = 'NULL';
}
return $value;
}
/**
* Apply in_quotes logic to an array. Note that keys beginning with
* datetime_ will be ommitted automatically.
*/
public static function array_in_quotes($array, $ommit_keys = Array()) {
// Loop array and apply in_quotes logic where needed
foreach ($array as $key => $value) {
if (!in_array($key, $ommit_keys) && substr($key, 0, strlen('datetime_')) != 'datetime_') {
$array[$key] = self::in_quotes($value);
}
}
return $array;
}
/**
* Turn a mysqli results object into an array where the developer
* decides which column of the results set to use as the value.
* Optionally, the developer can decide which column to use as
* the associative key
*/
public static function results_to_array($mysqli_results_object, $column_as_value, $column_as_key = NULL) {
$results_array = Array();
while ($row = $mysqli_results_object->fetch_assoc()) {
if (!empty($column_as_key)) {
$results_array[$row[$column_as_key]] = $row[$column_as_value];
} else {
$results_array[] = $row[$column_as_value];
}
}
return $results_array;
}
/**
* Get the next Auto Increment value of a table
*/
public static function auto_increment($table) {
// SQL
$sql = "SHOW TABLE STATUS LIKE '{$table}'";
// Execute
$results = self::execute($sql);
$row = $results->fetch_assoc();
return $row['Auto_increment'];
}
}