├── .gitignore ├── README.md ├── example-data.sql ├── example.php └── class.db.php /.gitignore: -------------------------------------------------------------------------------- 1 | *.tmproj 2 | *.DS_Store 3 | testfile.php 4 | tests/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SimpleMysqli 2 | ============= 3 | 4 | PHP class to access MySQL database wrapper using MySQLi 5 | 6 | This class can: 7 | 8 | - Connect to a given MySQL server 9 | - Execute arbitrary SQL queries 10 | - Retrieve the number of query result rows, result columns and last inserted table identifier 11 | - Retrieve the query results in a single array 12 | - Escape a single string or an array of literal text values to use in queries 13 | - Determine if one value or an array of values contain common MySQL function calls 14 | - Check of a table exists 15 | - Check of a given table record exists 16 | - Return a query result that has just one row 17 | - Execute INSERT, UPDATE and DELETE queries from values that define tables, field names, field values and conditions 18 | - Truncate a table 19 | - Send email messages with MySQL access and query errors 20 | - Display the total number of queries performed during all instances of the class 21 | 22 | Full usage examples are provided in example.php, using example data provided in example-data.sql -------------------------------------------------------------------------------- /example-data.sql: -------------------------------------------------------------------------------- 1 | # ************************************************************ 2 | # Sequel Pro SQL dump 3 | # Version 4004 4 | # 5 | # http://www.sequelpro.com/ 6 | # http://code.google.com/p/sequel-pro/ 7 | # 8 | # Host: 127.0.0.1 (MySQL 5.5.9) 9 | # Database: rapidphpme 10 | # Generation Time: 2013-02-15 22:36:17 +0000 11 | # ************************************************************ 12 | 13 | 14 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 15 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 16 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 17 | /*!40101 SET NAMES utf8 */; 18 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 19 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 20 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 21 | 22 | 23 | # Dump of table example_phpmvc 24 | # ------------------------------------------------------------ 25 | 26 | 27 | DROP TABLE IF EXISTS `example_phpmvc`; 28 | 29 | CREATE TABLE `example_phpmvc` ( 30 | `group_id` int(11) unsigned NOT NULL AUTO_INCREMENT, 31 | `group_parent` int(11) NOT NULL DEFAULT '0', 32 | `group_name` varchar(220) DEFAULT NULL, 33 | PRIMARY KEY (`group_id`) 34 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 35 | 36 | LOCK TABLES `example_phpmvc` WRITE; 37 | /*!40000 ALTER TABLE `example_phpmvc` DISABLE KEYS */; 38 | 39 | INSERT INTO `example_phpmvc` (`group_id`, `group_parent`, `group_name`) 40 | VALUES 41 | (1,0,'Bookmarks Menu'), 42 | (2,0,'Web Dev'), 43 | (3,0,'School'), 44 | (4,0,'Work'), 45 | (8,0,'Music'), 46 | (9,0,'News'), 47 | (10,2,'CSS'), 48 | (11,2,'PHP'), 49 | (12,2,'HTML'), 50 | (13,2,'jQuery'), 51 | (14,2,'Graphics'), 52 | (15,8,'Production Tools'), 53 | (16,8,'Samples'), 54 | (17,8,'Forums'), 55 | (18,8,'Labels'), 56 | (19,2,'Tools'), 57 | (20,2,'Tips'), 58 | (21,2,'User Interface'), 59 | (22,2,'Resources'), 60 | (23,0,'Shopping'), 61 | (24,0,'Travel'), 62 | (25,2,'SEO'), 63 | (26,24,'Properties'), 64 | (27,2,'Databases'), 65 | (28,2,'MySQL'); 66 | 67 | /*!40000 ALTER TABLE `example_phpmvc` ENABLE KEYS */; 68 | UNLOCK TABLES; 69 | 70 | 71 | 72 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 73 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; 74 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; 75 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 76 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 77 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 78 | -------------------------------------------------------------------------------- /example.php: -------------------------------------------------------------------------------- 1 | $value ) 34 | { 35 | $_POST[$key] = $database->filter( $value ); 36 | } 37 | } 38 | echo '
';
 39 | print_r($_POST);
 40 | echo '
'; 41 | 42 | /** 43 | * Auto filter an entire array 44 | */ 45 | $array = array( 46 | 'name' => array( 'first' => '"Super awesome"' ), 47 | 'email' => '%&& "'single quotes are awesome'" 49 | ); 50 | $array = $database->filter( $array ); 51 | echo '
';
 52 | print_r($array);
 53 | echo '
'; 54 | 55 | 56 | /** 57 | * Retrieve results of a standard query 58 | */ 59 | $query = "SELECT group_name FROM example_phpmvc"; 60 | $results = $database->get_results( $query ); 61 | foreach( $results as $row ) 62 | { 63 | echo $row['group_name'] .'
'; 64 | } 65 | 66 | 67 | /** 68 | * Retrieving a single row of data 69 | */ 70 | $query = "SELECT group_id, group_name, group_parent FROM example_phpmvc WHERE group_name LIKE '%Awesome%'"; 71 | if( $database->num_rows( $query ) > 0 ) 72 | { 73 | list( $id, $name, $parent ) = $database->get_row( $query ); 74 | echo "

With an ID of $id, $name has a parent of $parent

"; 75 | } 76 | else 77 | { 78 | echo 'No results found for a group name like "production"'; 79 | } 80 | 81 | 82 | /** 83 | * Inserting data 84 | */ 85 | //The fields and values to insert 86 | $names = array( 87 | 'group_parent' => 18, 88 | 'group_name' => mt_rand(0, 500) //Random thing to insert 89 | ); 90 | $add_query = $database->insert( 'example_phpmvc', $names ); 91 | if( $add_query ) 92 | { 93 | echo '

Successfully inserted "'. $names['group_name']. '" into the database.

'; 94 | } 95 | 96 | $last = $database->lastid(); 97 | 98 | 99 | /** 100 | * Insert multiple records in single query 101 | */ 102 | //Field names 103 | $fields = array( 104 | 'group_parent', 105 | 'group_name' 106 | ); 107 | //Values to insert 108 | $records = array( 109 | array( 110 | 9, 'Record 9' 111 | ), 112 | array( 113 | 7, 'Record 7' 114 | ), 115 | array( 116 | 7, 'Nick', 'nick@nick.com', 1, 'This will not be added' 117 | ), 118 | array( 119 | 2, 'This is awesome' 120 | ) 121 | ); 122 | $inserted = $database->insert_multi( 'example_phpmvc', $fields, $records ); 123 | if( $inserted ) 124 | { 125 | echo '

'.$inserted .' records inserted

'; 126 | } 127 | 128 | 129 | /** 130 | * Updating data 131 | */ 132 | //Fields and values to update 133 | $update = array( 134 | 'group_name' => md5( mt_rand(0, 500) ), 135 | 'group_parent' => 91 136 | ); 137 | //Add the WHERE clauses 138 | $where_clause = array( 139 | 'group_id' => $last 140 | ); 141 | $updated = $database->update( 'example_phpmvc', $update, $where_clause, 1 ); 142 | if( $updated ) 143 | { 144 | echo '

Successfully updated '.$where_clause['group_id']. ' to '. $update['group_name'].'

'; 145 | } 146 | 147 | /** 148 | * Deleting data 149 | */ 150 | //Run a query to delete rows from table where id = 3 and name = Awesome, LIMIT 1 151 | $delete = array( 152 | 'group_id' => 15, 153 | 'group_name' => 'Production Tools (updated)' 154 | ); 155 | $deleted = $database->delete( 'example_phpmvc', $delete, 1 ); 156 | if( $deleted ) 157 | { 158 | echo '

Successfully deleted '.$delete['group_name'] .' from the database.

'; 159 | } 160 | 161 | 162 | /** 163 | * Checking to see if a value exists 164 | */ 165 | $check_column = 'group_id'; 166 | $check_for = array( 'group_name' => 'Resources' ); 167 | $exists = $database->exists( 'example_phpmvc', $check_column, $check_for ); 168 | if( $exists ) 169 | { 170 | echo '

Bennett DOES exist!

'; 171 | } 172 | 173 | 174 | /** 175 | * Checking to see if a table exists 176 | */ 177 | if( !$database->table_exists( 'example_phpmvc' ) ) 178 | { 179 | //Run a table install, the table doesn't exist 180 | } 181 | 182 | 183 | /** 184 | * Truncating tables 185 | * Commented out intentionally (just in case!) 186 | */ 187 | //Truncate a single table, no output display 188 | //$truncate = $database->truncate( array('example_phpmvc') ); 189 | 190 | //Truncate multiple tables, display number of tables truncated 191 | //echo $database->truncate( array('example_phpmvc', 'my_other_table') ); 192 | 193 | 194 | /** 195 | * List the fields in a table 196 | */ 197 | $fields = $database->list_fields( "SELECT * FROM example_phpmvc" ); 198 | echo '
';
199 | print_r( $fields );
200 | echo '
'; 201 | 202 | 203 | /** 204 | * Output the number of fields in a table 205 | */ 206 | echo $database->num_fields( "SELECT * FROM example_phpmvc" ); 207 | 208 | 209 | /** 210 | * Display the number of queries performed by the class 211 | * Applies across multiple instances of the DB class 212 | */ 213 | echo '
' . $database->total_queries(); -------------------------------------------------------------------------------- /class.db.php: -------------------------------------------------------------------------------- 1 | Error at '. date('Y-m-d H:i:s').':

'; 64 | $message .= '

Query: '. htmlentities( $query ).'
'; 65 | $message .= 'Error: ' . $error; 66 | $message .= '

'; 67 | 68 | if( defined( 'SEND_ERRORS_TO' ) ) 69 | { 70 | $headers = 'MIME-Version: 1.0' . "\r\n"; 71 | $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n"; 72 | $headers .= 'To: Admin <'.SEND_ERRORS_TO.'>' . "\r\n"; 73 | $headers .= 'From: Yoursite ' . "\r\n"; 74 | 75 | mail( SEND_ERRORS_TO, 'Database Error', $message, $headers ); 76 | } 77 | else 78 | { 79 | trigger_error( $message ); 80 | } 81 | 82 | if( !defined( 'DISPLAY_DEBUG' ) || ( defined( 'DISPLAY_DEBUG' ) && DISPLAY_DEBUG ) ) 83 | { 84 | echo $message; 85 | } 86 | } 87 | 88 | 89 | public function __construct() 90 | { 91 | mb_internal_encoding( 'UTF-8' ); 92 | mb_regex_encoding( 'UTF-8' ); 93 | mysqli_report( MYSQLI_REPORT_STRICT ); 94 | try { 95 | $this->link = new mysqli( DB_HOST, DB_USER, DB_PASS, DB_NAME ); 96 | $this->link->set_charset( "utf8" ); 97 | } catch ( Exception $e ) { 98 | die( 'Unable to connect to database' ); 99 | } 100 | } 101 | 102 | public function __destruct() 103 | { 104 | if( $this->link) 105 | { 106 | $this->disconnect(); 107 | } 108 | } 109 | 110 | 111 | /** 112 | * Sanitize user data 113 | * 114 | * Example usage: 115 | * $user_name = $database->filter( $_POST['user_name'] ); 116 | * 117 | * Or to filter an entire array: 118 | * $data = array( 'name' => $_POST['name'], 'email' => 'email@address.com' ); 119 | * $data = $database->filter( $data ); 120 | * 121 | * @access public 122 | * @param mixed $data 123 | * @return mixed $data 124 | */ 125 | public function filter( $data ) 126 | { 127 | if( !is_array( $data ) ) 128 | { 129 | $data = $this->link->real_escape_string( $data ); 130 | $data = trim( htmlentities( $data, ENT_QUOTES, 'UTF-8', false ) ); 131 | } 132 | else 133 | { 134 | //Self call function to sanitize array data 135 | $data = array_map( array( $this, 'filter' ), $data ); 136 | } 137 | return $data; 138 | } 139 | 140 | 141 | /** 142 | * Extra function to filter when only mysqli_real_escape_string is needed 143 | * @access public 144 | * @param mixed $data 145 | * @return mixed $data 146 | */ 147 | public function escape( $data ) 148 | { 149 | if( !is_array( $data ) ) 150 | { 151 | $data = $this->link->real_escape_string( $data ); 152 | } 153 | else 154 | { 155 | //Self call function to sanitize array data 156 | $data = array_map( array( $this, 'escape' ), $data ); 157 | } 158 | return $data; 159 | } 160 | 161 | 162 | /** 163 | * Normalize sanitized data for display (reverse $database->filter cleaning) 164 | * 165 | * Example usage: 166 | * echo $database->clean( $data_from_database ); 167 | * 168 | * @access public 169 | * @param string $data 170 | * @return string $data 171 | */ 172 | public function clean( $data ) 173 | { 174 | $data = stripslashes( $data ); 175 | $data = html_entity_decode( $data, ENT_QUOTES, 'UTF-8' ); 176 | $data = nl2br( $data ); 177 | $data = urldecode( $data ); 178 | return $data; 179 | } 180 | 181 | 182 | /** 183 | * Determine if common non-encapsulated fields are being used 184 | * 185 | * Example usage: 186 | * if( $database->db_common( $query ) ) 187 | * { 188 | * //Do something 189 | * } 190 | * Used by function exists 191 | * 192 | * @access public 193 | * @param string 194 | * @param array 195 | * @return bool 196 | * 197 | */ 198 | public function db_common( $value = '' ) 199 | { 200 | if( is_array( $value ) ) 201 | { 202 | foreach( $value as $v ) 203 | { 204 | if( preg_match( '/AES_DECRYPT/i', $v ) || preg_match( '/AES_ENCRYPT/i', $v ) || preg_match( '/now()/i', $v ) ) 205 | { 206 | return true; 207 | } 208 | else 209 | { 210 | return false; 211 | } 212 | } 213 | } 214 | else 215 | { 216 | if( preg_match( '/AES_DECRYPT/i', $value ) || preg_match( '/AES_ENCRYPT/i', $value ) || preg_match( '/now()/i', $value ) ) 217 | { 218 | return true; 219 | } 220 | } 221 | } 222 | 223 | 224 | /** 225 | * Perform queries 226 | * All following functions run through this function 227 | * 228 | * @access public 229 | * @param string 230 | * @return string 231 | * @return array 232 | * @return bool 233 | * 234 | */ 235 | public function query( $query ) 236 | { 237 | $full_query = $this->link->query( $query ); 238 | if( $this->link->error ) 239 | { 240 | $this->log_db_errors( $this->link->error, $query ); 241 | return false; 242 | } 243 | else 244 | { 245 | return true; 246 | } 247 | } 248 | 249 | 250 | /** 251 | * Determine if database table exists 252 | * Example usage: 253 | * if( !$database->table_exists( 'checkingfortable' ) ) 254 | * { 255 | * //Install your table or throw error 256 | * } 257 | * 258 | * @access public 259 | * @param string 260 | * @return bool 261 | * 262 | */ 263 | public function table_exists( $name ) 264 | { 265 | self::$counter++; 266 | $check = $this->link->query( "SELECT 1 FROM $name" ); 267 | if($check !== false) 268 | { 269 | if( $check->num_rows > 0 ) 270 | { 271 | return true; 272 | } 273 | else 274 | { 275 | return false; 276 | } 277 | } 278 | else 279 | { 280 | return false; 281 | } 282 | } 283 | 284 | 285 | /** 286 | * Count number of rows found matching a specific query 287 | * 288 | * Example usage: 289 | * $rows = $database->num_rows( "SELECT id FROM users WHERE user_id = 44" ); 290 | * 291 | * @access public 292 | * @param string 293 | * @return int 294 | * 295 | */ 296 | public function num_rows( $query ) 297 | { 298 | self::$counter++; 299 | $num_rows = $this->link->query( $query ); 300 | if( $this->link->error ) 301 | { 302 | $this->log_db_errors( $this->link->error, $query ); 303 | return $this->link->error; 304 | } 305 | else 306 | { 307 | return $num_rows->num_rows; 308 | } 309 | } 310 | 311 | 312 | /** 313 | * Run check to see if value exists, returns true or false 314 | * 315 | * Example Usage: 316 | * $check_user = array( 317 | * 'user_email' => 'someuser@gmail.com', 318 | * 'user_id' => 48 319 | * ); 320 | * $exists = $database->exists( 'your_table', 'user_id', $check_user ); 321 | * 322 | * @access public 323 | * @param string database table name 324 | * @param string field to check (i.e. 'user_id' or COUNT(user_id)) 325 | * @param array column name => column value to match 326 | * @return bool 327 | * 328 | */ 329 | public function exists( $table = '', $check_val = '', $params = array() ) 330 | { 331 | self::$counter++; 332 | if( empty($table) || empty($check_val) || empty($params) ) 333 | { 334 | return false; 335 | } 336 | $check = array(); 337 | foreach( $params as $field => $value ) 338 | { 339 | if( !empty( $field ) && !empty( $value ) ) 340 | { 341 | //Check for frequently used mysql commands and prevent encapsulation of them 342 | if( $this->db_common( $value ) ) 343 | { 344 | $check[] = "$field = $value"; 345 | } 346 | else 347 | { 348 | $check[] = "$field = '$value'"; 349 | } 350 | } 351 | 352 | } 353 | $check = implode(' AND ', $check); 354 | 355 | $rs_check = "SELECT $check_val FROM ".$table." WHERE $check"; 356 | $number = $this->num_rows( $rs_check ); 357 | if( $number === 0 ) 358 | { 359 | return false; 360 | } 361 | else 362 | { 363 | return true; 364 | } 365 | } 366 | 367 | 368 | /** 369 | * Return specific row based on db query 370 | * 371 | * Example usage: 372 | * list( $name, $email ) = $database->get_row( "SELECT name, email FROM users WHERE user_id = 44" ); 373 | * 374 | * @access public 375 | * @param string 376 | * @param bool $object (true returns results as objects) 377 | * @return array 378 | * 379 | */ 380 | public function get_row( $query, $object = false ) 381 | { 382 | self::$counter++; 383 | $row = $this->link->query( $query ); 384 | if( $this->link->error ) 385 | { 386 | $this->log_db_errors( $this->link->error, $query ); 387 | return false; 388 | } 389 | else 390 | { 391 | $r = ( !$object ) ? $row->fetch_row() : $row->fetch_object(); 392 | return $r; 393 | } 394 | } 395 | 396 | 397 | /** 398 | * Perform query to retrieve array of associated results 399 | * 400 | * Example usage: 401 | * $users = $database->get_results( "SELECT name, email FROM users ORDER BY name ASC" ); 402 | * foreach( $users as $user ) 403 | * { 404 | * echo $user['name'] . ': '. $user['email'] .'
'; 405 | * } 406 | * 407 | * @access public 408 | * @param string 409 | * @param bool $object (true returns object) 410 | * @return array 411 | * 412 | */ 413 | public function get_results( $query, $object = false ) 414 | { 415 | self::$counter++; 416 | //Overwrite the $row var to null 417 | $row = null; 418 | 419 | $results = $this->link->query( $query ); 420 | if( $this->link->error ) 421 | { 422 | $this->log_db_errors( $this->link->error, $query ); 423 | return false; 424 | } 425 | else 426 | { 427 | $row = array(); 428 | while( $r = ( !$object ) ? $results->fetch_assoc() : $results->fetch_object() ) 429 | { 430 | $row[] = $r; 431 | } 432 | return $row; 433 | } 434 | } 435 | 436 | 437 | /** 438 | * Insert data into database table 439 | * 440 | * Example usage: 441 | * $user_data = array( 442 | * 'name' => 'Bennett', 443 | * 'email' => 'email@address.com', 444 | * 'active' => 1 445 | * ); 446 | * $database->insert( 'users_table', $user_data ); 447 | * 448 | * @access public 449 | * @param string table name 450 | * @param array table column => column value 451 | * @return bool 452 | * 453 | */ 454 | public function insert( $table, $variables = array() ) 455 | { 456 | self::$counter++; 457 | //Make sure the array isn't empty 458 | if( empty( $variables ) ) 459 | { 460 | return false; 461 | } 462 | 463 | $sql = "INSERT INTO ". $table; 464 | $fields = array(); 465 | $values = array(); 466 | foreach( $variables as $field => $value ) 467 | { 468 | $fields[] = $field; 469 | $values[] = "'".$value."'"; 470 | } 471 | $fields = ' (' . implode(', ', $fields) . ')'; 472 | $values = '('. implode(', ', $values) .')'; 473 | 474 | $sql .= $fields .' VALUES '. $values; 475 | 476 | $query = $this->link->query( $sql ); 477 | 478 | if( $this->link->error ) 479 | { 480 | //return false; 481 | $this->log_db_errors( $this->link->error, $sql ); 482 | return false; 483 | } 484 | else 485 | { 486 | return true; 487 | } 488 | } 489 | 490 | 491 | /** 492 | * Insert data KNOWN TO BE SECURE into database table 493 | * Ensure that this function is only used with safe data 494 | * No class-side sanitizing is performed on values found to contain common sql commands 495 | * As dictated by the db_common function 496 | * All fields are assumed to be properly encapsulated before initiating this function 497 | * 498 | * @access public 499 | * @param string table name 500 | * @param array table column => column value 501 | * @return bool 502 | */ 503 | public function insert_safe( $table, $variables = array() ) 504 | { 505 | self::$counter++; 506 | //Make sure the array isn't empty 507 | if( empty( $variables ) ) 508 | { 509 | return false; 510 | } 511 | 512 | $sql = "INSERT INTO ". $table; 513 | $fields = array(); 514 | $values = array(); 515 | foreach( $variables as $field => $value ) 516 | { 517 | $fields[] = $this->filter( $field ); 518 | //Check for frequently used mysql commands and prevent encapsulation of them 519 | $values[] = $value; 520 | } 521 | $fields = ' (' . implode(', ', $fields) . ')'; 522 | $values = '('. implode(', ', $values) .')'; 523 | 524 | $sql .= $fields .' VALUES '. $values; 525 | $query = $this->link->query( $sql ); 526 | 527 | if( $this->link->error ) 528 | { 529 | $this->log_db_errors( $this->link->error, $sql ); 530 | return false; 531 | } 532 | else 533 | { 534 | return true; 535 | } 536 | } 537 | 538 | 539 | /** 540 | * Insert multiple records in a single query into a database table 541 | * 542 | * Example usage: 543 | * $fields = array( 544 | * 'name', 545 | * 'email', 546 | * 'active' 547 | * ); 548 | * $records = array( 549 | * array( 550 | * 'Bennett', 'bennett@email.com', 1 551 | * ), 552 | * array( 553 | * 'Lori', 'lori@email.com', 0 554 | * ), 555 | * array( 556 | * 'Nick', 'nick@nick.com', 1, 'This will not be added' 557 | * ), 558 | * array( 559 | * 'Meghan', 'meghan@email.com', 1 560 | * ) 561 | * ); 562 | * $database->insert_multi( 'users_table', $fields, $records ); 563 | * 564 | * @access public 565 | * @param string table name 566 | * @param array table columns 567 | * @param nested array records 568 | * @return bool 569 | * @return int number of records inserted 570 | * 571 | */ 572 | public function insert_multi( $table, $columns = array(), $records = array() ) 573 | { 574 | self::$counter++; 575 | //Make sure the arrays aren't empty 576 | if( empty( $columns ) || empty( $records ) ) 577 | { 578 | return false; 579 | } 580 | 581 | //Count the number of fields to ensure insertion statements do not exceed the same num 582 | $number_columns = count( $columns ); 583 | 584 | //Start a counter for the rows 585 | $added = 0; 586 | 587 | //Start the query 588 | $sql = "INSERT INTO ". $table; 589 | 590 | $fields = array(); 591 | //Loop through the columns for insertion preparation 592 | foreach( $columns as $field ) 593 | { 594 | $fields[] = '`'.$field.'`'; 595 | } 596 | $fields = ' (' . implode(', ', $fields) . ')'; 597 | 598 | //Loop through the records to insert 599 | $values = array(); 600 | foreach( $records as $record ) 601 | { 602 | //Only add a record if the values match the number of columns 603 | if( count( $record ) == $number_columns ) 604 | { 605 | $values[] = '(\''. implode( '\', \'', array_values( $record ) ) .'\')'; 606 | $added++; 607 | } 608 | } 609 | $values = implode( ', ', $values ); 610 | 611 | $sql .= $fields .' VALUES '. $values; 612 | 613 | $query = $this->link->query( $sql ); 614 | 615 | if( $this->link->error ) 616 | { 617 | $this->log_db_errors( $this->link->error, $sql ); 618 | return false; 619 | } 620 | else 621 | { 622 | return $added; 623 | } 624 | } 625 | 626 | 627 | /** 628 | * Update data in database table 629 | * 630 | * Example usage: 631 | * $update = array( 'name' => 'Not bennett', 'email' => 'someotheremail@email.com' ); 632 | * $update_where = array( 'user_id' => 44, 'name' => 'Bennett' ); 633 | * $database->update( 'users_table', $update, $update_where, 1 ); 634 | * 635 | * @access public 636 | * @param string table name 637 | * @param array values to update table column => column value 638 | * @param array where parameters table column => column value 639 | * @param int limit 640 | * @return bool 641 | * 642 | */ 643 | public function update( $table, $variables = array(), $where = array(), $limit = '' ) 644 | { 645 | self::$counter++; 646 | //Make sure the required data is passed before continuing 647 | //This does not include the $where variable as (though infrequently) 648 | //queries are designated to update entire tables 649 | if( empty( $variables ) ) 650 | { 651 | return false; 652 | } 653 | $sql = "UPDATE ". $table ." SET "; 654 | foreach( $variables as $field => $value ) 655 | { 656 | 657 | $updates[] = "`$field` = '$value'"; 658 | } 659 | $sql .= implode(', ', $updates); 660 | 661 | //Add the $where clauses as needed 662 | if( !empty( $where ) ) 663 | { 664 | foreach( $where as $field => $value ) 665 | { 666 | $value = $value; 667 | 668 | $clause[] = "$field = '$value'"; 669 | } 670 | $sql .= ' WHERE '. implode(' AND ', $clause); 671 | } 672 | 673 | if( !empty( $limit ) ) 674 | { 675 | $sql .= ' LIMIT '. $limit; 676 | } 677 | 678 | $query = $this->link->query( $sql ); 679 | 680 | if( $this->link->error ) 681 | { 682 | $this->log_db_errors( $this->link->error, $sql ); 683 | return false; 684 | } 685 | else 686 | { 687 | return true; 688 | } 689 | } 690 | 691 | 692 | /** 693 | * Delete data from table 694 | * 695 | * Example usage: 696 | * $where = array( 'user_id' => 44, 'email' => 'someotheremail@email.com' ); 697 | * $database->delete( 'users_table', $where, 1 ); 698 | * 699 | * @access public 700 | * @param string table name 701 | * @param array where parameters table column => column value 702 | * @param int max number of rows to remove. 703 | * @return bool 704 | * 705 | */ 706 | public function delete( $table, $where = array(), $limit = '' ) 707 | { 708 | self::$counter++; 709 | //Delete clauses require a where param, otherwise use "truncate" 710 | if( empty( $where ) ) 711 | { 712 | return false; 713 | } 714 | 715 | $sql = "DELETE FROM ". $table; 716 | foreach( $where as $field => $value ) 717 | { 718 | $value = $value; 719 | $clause[] = "$field = '$value'"; 720 | } 721 | $sql .= " WHERE ". implode(' AND ', $clause); 722 | 723 | if( !empty( $limit ) ) 724 | { 725 | $sql .= " LIMIT ". $limit; 726 | } 727 | 728 | $query = $this->link->query( $sql ); 729 | 730 | if( $this->link->error ) 731 | { 732 | //return false; // 733 | $this->log_db_errors( $this->link->error, $sql ); 734 | return false; 735 | } 736 | else 737 | { 738 | return true; 739 | } 740 | } 741 | 742 | 743 | /** 744 | * Get last auto-incrementing ID associated with an insertion 745 | * 746 | * Example usage: 747 | * $database->insert( 'users_table', $user ); 748 | * $last = $database->lastid(); 749 | * 750 | * @access public 751 | * @param none 752 | * @return int 753 | * 754 | */ 755 | public function lastid() 756 | { 757 | self::$counter++; 758 | return $this->link->insert_id; 759 | } 760 | 761 | 762 | /** 763 | * Return the number of rows affected by a given query 764 | * 765 | * Example usage: 766 | * $database->insert( 'users_table', $user ); 767 | * $database->affected(); 768 | * 769 | * @access public 770 | * @param none 771 | * @return int 772 | */ 773 | public function affected() 774 | { 775 | return $this->link->affected_rows; 776 | } 777 | 778 | 779 | /** 780 | * Get number of fields 781 | * 782 | * Example usage: 783 | * echo $database->num_fields( "SELECT * FROM users_table" ); 784 | * 785 | * @access public 786 | * @param query 787 | * @return int 788 | */ 789 | public function num_fields( $query ) 790 | { 791 | self::$counter++; 792 | $query = $this->link->query( $query ); 793 | $fields = $query->field_count; 794 | return $fields; 795 | } 796 | 797 | 798 | /** 799 | * Get field names associated with a table 800 | * 801 | * Example usage: 802 | * $fields = $database->list_fields( "SELECT * FROM users_table" ); 803 | * echo '
';
804 |      * print_r( $fields );
805 |      * echo '
'; 806 | * 807 | * @access public 808 | * @param query 809 | * @return array 810 | */ 811 | public function list_fields( $query ) 812 | { 813 | self::$counter++; 814 | $query = $this->link->query( $query ); 815 | $listed_fields = $query->fetch_fields(); 816 | return $listed_fields; 817 | } 818 | 819 | 820 | /** 821 | * Truncate entire tables 822 | * 823 | * Example usage: 824 | * $remove_tables = array( 'users_table', 'user_data' ); 825 | * echo $database->truncate( $remove_tables ); 826 | * 827 | * @access public 828 | * @param array database table names 829 | * @return int number of tables truncated 830 | * 831 | */ 832 | public function truncate( $tables = array() ) 833 | { 834 | if( !empty( $tables ) ) 835 | { 836 | $truncated = 0; 837 | foreach( $tables as $table ) 838 | { 839 | $truncate = "TRUNCATE TABLE `".trim($table)."`"; 840 | $this->link->query( $truncate ); 841 | if( !$this->link->error ) 842 | { 843 | $truncated++; 844 | self::$counter++; 845 | } 846 | } 847 | return $truncated; 848 | } 849 | } 850 | 851 | 852 | /** 853 | * Output results of queries 854 | * 855 | * @access public 856 | * @param string variable 857 | * @param bool echo [true,false] defaults to true 858 | * @return string 859 | * 860 | */ 861 | public function display( $variable, $echo = true ) 862 | { 863 | $out = ''; 864 | if( !is_array( $variable ) ) 865 | { 866 | $out .= $variable; 867 | } 868 | else 869 | { 870 | $out .= '
';
871 |             $out .= print_r( $variable, TRUE );
872 |             $out .= '
'; 873 | } 874 | if( $echo === true ) 875 | { 876 | echo $out; 877 | } 878 | else 879 | { 880 | return $out; 881 | } 882 | } 883 | 884 | 885 | /** 886 | * Output the total number of queries 887 | * Generally designed to be used at the bottom of a page after 888 | * scripts have been run and initialized as needed 889 | * 890 | * Example usage: 891 | * echo 'There were '. $database->total_queries() . ' performed'; 892 | * 893 | * @access public 894 | * @param none 895 | * @return int 896 | */ 897 | public function total_queries() 898 | { 899 | return self::$counter; 900 | } 901 | 902 | 903 | /** 904 | * Singleton function 905 | * 906 | * Example usage: 907 | * $database = DB::getInstance(); 908 | * 909 | * @access private 910 | * @return self 911 | */ 912 | static function getInstance() 913 | { 914 | if( self::$inst == null ) 915 | { 916 | self::$inst = new DB(); 917 | } 918 | return self::$inst; 919 | } 920 | 921 | 922 | /** 923 | * Disconnect from db server 924 | * Called automatically from __destruct function 925 | */ 926 | public function disconnect() 927 | { 928 | $this->link->close(); 929 | } 930 | 931 | } //end class DB --------------------------------------------------------------------------------