├── .github └── FUNDING.yml ├── LICENSE.txt ├── README.md ├── composer.json └── src └── Database.php /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [dcblogdev] 4 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020 Dcblogdev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PDO Wrapper 2 | 3 | This PDO wrapper, is a collection of methods for working with a database this includes selecting, inserting, updating and deleting records. 4 | 5 | > V2+ has been rewritten for the old docs please see [V1 branch](https://github.com/dcblogdev/pdo-wrapper/tree/v1) 6 | 7 | [](https://packagist.org/packages/dcblogdev/pdo-wrapper) 8 | [](https://packagist.org/packages/dcblogdev/pdo-wrapper) 9 | 10 |  11 | 12 | 13 | This PDO wrapper, is a collection of methods for working with a database this includes selecting, inserting, updating and deleting records. 14 | 15 | > V2+ has been rewritten for the old docs please see [V1 branch](https://github.com/dcblogdev/pdo-wrapper/tree/v1) 16 | 17 | ## Upgrade from V1 18 | 19 | Version 2 is now namespaced as `Dcblogdev` instead of `Daveismyname` 20 | 21 | Also the methods `get()` and `select()` have been removed. 22 | 23 | Instead of ::get() a new instance of the class used `new Database($args)` 24 | 25 | Select has been replaced with `->rows()` and `->row()` or `->run()` 26 | 27 | # Quick Reference 28 | ```php 29 | //create table 30 | $db->raw("CREATE TABLE demo (id int auto_increment primary key, name varchar(255))"); 31 | 32 | //use PDO directly 33 | $db->getPdo()->query('Select username FROM users')->fetchAll(); 34 | 35 | //use run to query and chain methods 36 | $db->run("SELECT * FROM users")->fetchAll(); 37 | $db->run("SELECT * FROM users")->fetch(); 38 | $db->run("SELECT * FROM users WHERE id = ?", [$id])->fetch(); 39 | //select using array instead of object 40 | $db->run("SELECT * FROM users")->fetch(PDO::FETCH_ASSOC); 41 | 42 | //get by id 43 | $db->getById('users', 2); 44 | 45 | //get all rows 46 | $db->rows("SELECT title FROM posts"); 47 | //get all rows with placeholders 48 | $db->rows("SELECT title FROM posts WHERE user_id = ?", [$user_id]); 49 | 50 | //get single row 51 | $db->row("SELECT title FROM posts"); 52 | //get single row with placeholders 53 | $db->row("SELECT title FROM posts WHERE user_id = ?", [$user_id]); 54 | 55 | //count 56 | $db->count("SELECT id FROM posts"); 57 | $db->count("SELECT id FROM posts WHERE category_id = ?", [$category_id]); 58 | 59 | //insert 60 | $id = $db->insert('users', ['username' => 'Dave', 'role' => 'Admin']); 61 | 62 | //last inserted id 63 | $db->lastInsertId()(); 64 | 65 | //update 66 | $db->update('users', ['role' => 'Editor'], ['id' => 3]); 67 | 68 | //delete from table with a where claus and a limit of 1 record 69 | $db->delete('posts', ['type_id' => 'draft'], $limit = 1); 70 | 71 | //delete from table with a where claus and a limit of 10 record 72 | $db->delete('posts', ['type_id' => 'draft'], $limit = 10); 73 | 74 | //delete all from table with a where claus and a limit of 10 record 75 | $db->delete('posts', ['type_id' => 'draft'], null); 76 | 77 | //delete all from table 78 | $db->deleteAll('posts'); 79 | 80 | //delete by id from table 81 | $db->deleteById('posts', 2); 82 | 83 | //delete by ids from table 84 | $db->deleteById('posts', '2,4,7'); 85 | 86 | //truncate table 87 | $db->truncate('posts'); 88 | ``` 89 | 90 | ## Install 91 | 92 | Using composer include the repository by typing the following into a terminal 93 | 94 | ``` 95 | composer require dcblogdev/pdo-wrapper 96 | ``` 97 | 98 | Set the DB credentials. Finally, create an instance of the classes. 99 | 100 | ```php 101 | use Dcblogdev\PdoWrapper\Database; 102 | 103 | // make a connection to mysql here 104 | $options = [ 105 | //required 106 | 'username' => '', 107 | 'database' => '', 108 | //optional 109 | 'password' => '', 110 | 'type' => 'mysql', 111 | 'charset' => 'utf8', 112 | 'host' => 'dev', 113 | 'port' => '3309' 114 | ]; 115 | 116 | $db = new Database($options); 117 | ``` 118 | 119 | Accessing PDO 120 | You can call getPdo()` to get access to PDO directly: 121 | 122 | ```php 123 | $db->getPdo() 124 | ``` 125 | 126 | This allows to chain calls: 127 | 128 | ```php 129 | $db->getPdo()->query($sql)->fetch(); 130 | ``` 131 | 132 | ## Querying 133 | 134 | All queries use prepared statements, calling ->run() returns a PDO option that can be chained: 135 | 136 | Select multiple records: 137 | 138 | ```php 139 | $db->run("select * FROM users")->fetchAll(); 140 | ``` 141 | 142 | Select a single record: 143 | 144 | ```php 145 | $db->run("select * FROM users")->fetch(); 146 | ``` 147 | 148 | Select multiple records using ->rows 149 | 150 | ```php 151 | $db->rows("select * FROM table"); 152 | ``` 153 | 154 | Select single record using ->row 155 | 156 | ```php 157 | $db->row("select * FROM table"); 158 | ``` 159 | 160 | To select records based on user data instead of passing the data to the query directly use a prepared statement, this is safer and stops any attempt at sql injections. 161 | 162 | Names placeholders 163 | 164 | ```php 165 | $db->row("select username FROM users WHERE id = :id and email = :email", ['id' => 1, ':email' => 'someone@domain.com']); 166 | ``` 167 | 168 | Annonomus placeholders 169 | 170 | ```php 171 | $db->row("select username FROM users WHERE id = ? and email = ?", [1, 'someone@domain.com']); 172 | ``` 173 | 174 | The above query will return the username from a users table where the id and email match. The id and email is passed seperartly in an array. 175 | 176 | Instead of passing in an id and email to the query directly a placeholder is used :id and :email (or ? can be used) then an array is passed the keys in the array matches the placeholder and is bound, so the database will get both the query and the bound data. 177 | 178 | Data returned from the query will be returns as an object this can be changed by passing a third param containing PDO::FETCH_ASSOC. 179 | 180 | To use the object loop through it, a typical example: 181 | 182 | ```php 183 | $rows = $db->rows("firstName, lastName FROM username ORDER BY firstName, lastName"); 184 | foreach ($rows as $row) { 185 | echo "
$row->firstName $row->lastName
"; 186 | } 187 | ``` 188 | 189 | ## Select Single Record 190 | 191 | Using row() will return only a single result. Like rows it accepts params being passed in an array as a second argument. 192 | 193 | Names placeholders 194 | 195 | ```php 196 | $db->row("column FROM table where id=:id", ['id' => 23]); 197 | ``` 198 | 199 | Anonymous placeholders 200 | 201 | ```php 202 | $db->row("column FROM table where id=?", [23]); 203 | ``` 204 | 205 | Another way to select a single record using the table and id by calling ->getById 206 | 207 | ```php 208 | $db->getById('users', $id); 209 | ``` 210 | 211 | ## Raw 212 | A raw query is a query that does not run through a prepared statement and will execute the query passed directly. Useful when creating a table. 213 | 214 | ```php 215 | $db->raw("CREATE TABLE IF NOT EXISTS users ( 216 | id INT(11) NOT NULL AUTO_INCREMENT, 217 | firstName VARCHAR(255) NOT NULL, 218 | lastnName VARCHAR(255) NOT NULL, 219 | email VARCHAR(255) NOT NULL, 220 | PRIMARY KEY (id))" 221 | ); 222 | ``` 223 | 224 | ## Count 225 | To count records call the count method. This method expects the table name and column name (optional). 226 | 227 | ```php 228 | $db->count('users'); 229 | ``` 230 | 231 | If the table has no column id 232 | 233 | ```php 234 | $db->count('users', 'user_id'); 235 | ``` 236 | 237 | ## Insert 238 | 239 | Data is inserted by calling the insert method it expects the table name followed by an array of key and values to insert in to the database. 240 | 241 | ```php 242 | $data = [ 243 | 'firstName' => 'Joe', 244 | 'lastnName' => 'Smith', 245 | 'email' => 'someone@domain.com' 246 | ]; 247 | $db->insert('users', $data); 248 | ``` 249 | 250 | The insert automatically returns the last inserted id by returning 'lastInsertId' to collect the id: 251 | 252 | ```php 253 | $id = $db->insert('users', $data); 254 | ``` 255 | 256 | ## Updating 257 | To update an existing record the update method is called. This method expects the table, array of data to update, and a second array containing the where condition. 258 | 259 | ```php 260 | $data = [ 261 | 'firstName' => 'Joe', 262 | 'lastnName' => 'Smith', 263 | 'email' => 'someone@domain.com' 264 | ]; 265 | $where = ['id' => 2]; 266 | $db->update('users', $data, $where); 267 | ``` 268 | 269 | Or: 270 | 271 | ```php 272 | $update = [ 273 | 'data' => [ 274 | 'firstName' => 'Joe', 275 | 'lastnName' => 'Smith', 276 | 'email' => 'someone@domain.com' 277 | ], 278 | 'where' => [ 279 | 'id' => 2 280 | ] 281 | ]; 282 | 283 | $db->update('users', $update['data'], $update['where']); 284 | ``` 285 | 286 | ## Delete 287 | 288 | To delete records call the delete method. This method expects the table name and an array of the where condition. 289 | 290 | ```php 291 | $where = ['id' => 2]; 292 | $db->delete('users', $where); 293 | ``` 294 | 295 | This will delete a single record to set the limit pass a third parameter containing the number to limit to or to remove the limit pass null as a third param. 296 | 297 | ```php 298 | $db->delete('users', $where, 10); //delete 10 records matcing the where 299 | $db->delete('users', $where, null); //delete all records matching the where 300 | ``` 301 | 302 | ## Delete All 303 | 304 | To delete all records for a given table 305 | 306 | ```php 307 | $db->deleteAll('users'); 308 | ``` 309 | 310 | ## Delete by Id 311 | 312 | To delete a record by its table and id 313 | 314 | ```php 315 | $db->deleteById('users', $id); 316 | ``` 317 | 318 | ## Delete Multiple In 319 | 320 | To delete multiple records where ids are in a specific column, this uses WHERE id IN (4,5,6) 321 | 322 | ```php 323 | $db->deleteByIds('users', 'id', '4,5,6'); 324 | ``` 325 | 326 | ## Truncate 327 | 328 | To empty a table of all contents call the truncate method. Passing only the table name. 329 | 330 | ```php 331 | $db->truncate('users'); 332 | ``` 333 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dcblogdev/pdo-wrapper", 3 | "description": "A crud wrapper for PDO", 4 | "license": "MIT", 5 | "authors": [ 6 | { 7 | "name": "David Carr", 8 | "email": "dave@dcblog.dev", 9 | "homepage": "https://dcblog.dev", 10 | "role": "Developer" 11 | } 12 | ], 13 | "require": { 14 | "php": ">=7.2" 15 | }, 16 | "autoload": { 17 | "psr-4": { 18 | "Dcblogdev\\PdoWrapper\\": "/src" 19 | } 20 | }, 21 | "minimum-stability": "dev" 22 | } 23 | -------------------------------------------------------------------------------- /src/Database.php: -------------------------------------------------------------------------------- 1 | db = new PDO("$type:host=$host;$port" . "dbname=$database;charset=$charset", $username, $password); 41 | $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 42 | } 43 | 44 | /** 45 | * get PDO instance 46 | * 47 | * @return $db PDO instance 48 | */ 49 | public function getPdo() 50 | { 51 | return $this->db; 52 | } 53 | 54 | /** 55 | * Run raw sql query 56 | * 57 | * @param string $sql sql query 58 | * @return void 59 | */ 60 | public function raw($sql) 61 | { 62 | $this->db->query($sql); 63 | } 64 | 65 | /** 66 | * Run sql query 67 | * 68 | * @param string $sql sql query 69 | * @param array $args params 70 | * @return object returns a PDO object 71 | */ 72 | public function run($sql, $args = []) 73 | { 74 | if (empty($args)) { 75 | return $this->db->query($sql); 76 | } 77 | 78 | $stmt = $this->db->prepare($sql); 79 | 80 | //check if args is associative or sequential? 81 | $is_assoc = (array() === $args) ? false : array_keys($args) !== range(0, count($args) - 1); 82 | if ($is_assoc) 83 | { 84 | foreach ($args as $key => $value) { 85 | if (is_int($value)) { 86 | $stmt->bindValue(":$key", $value, PDO::PARAM_INT); 87 | } else { 88 | $stmt->bindValue(":$key", $value); 89 | } 90 | } 91 | $stmt->execute(); 92 | } 93 | else 94 | { 95 | $stmt->execute($args); 96 | } 97 | 98 | return $stmt; 99 | } 100 | 101 | /** 102 | * Get arrrays of records 103 | * 104 | * @param string $sql sql query 105 | * @param array $args params 106 | * @param object $fetchMode set return mode ie object or array 107 | * @return object returns multiple records 108 | */ 109 | public function rows($sql, $args = [], $fetchMode = PDO::FETCH_OBJ) 110 | { 111 | return $this->run($sql, $args)->fetchAll($fetchMode); 112 | } 113 | 114 | /** 115 | * Get arrray of records 116 | * 117 | * @param string $sql sql query 118 | * @param array $args params 119 | * @param object $fetchMode set return mode ie object or array 120 | * @return object returns single record 121 | */ 122 | public function row($sql, $args = [], $fetchMode = PDO::FETCH_OBJ) 123 | { 124 | return $this->run($sql, $args)->fetch($fetchMode); 125 | } 126 | 127 | /** 128 | * Get record by id 129 | * 130 | * @param string $table name of table 131 | * @param integer $id id of record 132 | * @param object $fetchMode set return mode ie object or array 133 | * @return object returns single record 134 | */ 135 | public function getById($table, $id, $fetchMode = PDO::FETCH_OBJ) 136 | { 137 | return $this->run("SELECT * FROM $table WHERE id = ?", [$id])->fetch($fetchMode); 138 | } 139 | 140 | /** 141 | * Get number of records 142 | * 143 | * @param string $sql sql query 144 | * @param array $args params 145 | * @param object $fetchMode set return mode ie object or array 146 | * @return integer returns number of records 147 | */ 148 | public function count($sql, $args = []) 149 | { 150 | return $this->run($sql, $args)->rowCount(); 151 | } 152 | 153 | /** 154 | * Get primary key of last inserted record 155 | */ 156 | public function lastInsertId() 157 | { 158 | return $this->db->lastInsertId(); 159 | } 160 | 161 | /** 162 | * insert record 163 | * 164 | * @param string $table table name 165 | * @param array $data array of columns and values 166 | */ 167 | public function insert($table, $data) 168 | { 169 | // enclose columns in backticks 170 | $columns = array_map(function($column) { 171 | return '`' . trim($column, '`') . '`'; 172 | }, array_keys($data)); 173 | 174 | //add columns into comma seperated string 175 | $columns = implode(',', $columns); 176 | 177 | //get values 178 | $values = array_values($data); 179 | 180 | $placeholders = array_map(function ($val) { 181 | return '?'; 182 | }, array_keys($data)); 183 | 184 | //convert array into comma seperated string 185 | $placeholders = implode(',', array_values($placeholders)); 186 | 187 | $this->run("INSERT INTO $table ($columns) VALUES ($placeholders)", $values); 188 | 189 | return $this->lastInsertId(); 190 | } 191 | 192 | /** 193 | * update record 194 | * 195 | * @param string $table table name 196 | * @param array $data array of columns and values 197 | * @param array $where array of columns and values 198 | */ 199 | public function update($table, $data, $where) 200 | { 201 | //collect the values from data and where 202 | $values = []; 203 | 204 | //setup fields 205 | $fieldDetails = null; 206 | foreach ($data as $key => $value) { 207 | $key = '`' . trim($key, '`') . '`'; 208 | $fieldDetails .= "$key = ?,"; 209 | $values[] = $value; 210 | } 211 | $fieldDetails = rtrim($fieldDetails, ','); 212 | 213 | //setup where 214 | $whereDetails = null; 215 | $i = 0; 216 | foreach ($where as $key => $value) { 217 | $key = '`' . trim($key, '`') . '`'; 218 | $whereDetails .= $i == 0 ? "$key = ?" : " AND $key = ?"; 219 | $values[] = $value; 220 | $i++; 221 | } 222 | 223 | $stmt = $this->run("UPDATE $table SET $fieldDetails WHERE $whereDetails", $values); 224 | 225 | return $stmt->rowCount(); 226 | } 227 | 228 | /** 229 | * Delete records 230 | * 231 | * @param string $table table name 232 | * @param array $where array of columns and values 233 | * @param integer $limit limit number of records 234 | */ 235 | public function delete($table, $where, $limit = 1) 236 | { 237 | //collect the values from collection 238 | $values = array_values($where); 239 | 240 | //setup where 241 | $whereDetails = null; 242 | $i = 0; 243 | foreach ($where as $key => $value) { 244 | $key = '`' . trim($key, '`') . '`'; 245 | $whereDetails .= $i == 0 ? "$key = ?" : " AND $key = ?"; 246 | $i++; 247 | } 248 | 249 | //if limit is a number use a limit on the query 250 | if (is_numeric($limit)) { 251 | $limit = "LIMIT $limit"; 252 | } 253 | 254 | $stmt = $this->run("DELETE FROM $table WHERE $whereDetails $limit", $values); 255 | 256 | return $stmt->rowCount(); 257 | } 258 | 259 | /** 260 | * Delete all records records 261 | * 262 | * @param string $table table name 263 | */ 264 | public function deleteAll($table) 265 | { 266 | $stmt = $this->run("DELETE FROM $table"); 267 | 268 | return $stmt->rowCount(); 269 | } 270 | 271 | /** 272 | * Delete record by id 273 | * 274 | * @param string $table table name 275 | * @param integer $id id of record 276 | */ 277 | public function deleteById($table, $id) 278 | { 279 | $stmt = $this->run("DELETE FROM $table WHERE id = ?", [$id]); 280 | 281 | return $stmt->rowCount(); 282 | } 283 | 284 | /** 285 | * Delete record by ids 286 | * 287 | * @param string $table table name 288 | * @param string $column name of column 289 | * @param string $ids ids of records 290 | */ 291 | public function deleteByIds(string $table, string $column, string $ids) 292 | { 293 | $stmt = $this->run("DELETE FROM $table WHERE $column IN ($ids)"); 294 | 295 | return $stmt->rowCount(); 296 | } 297 | 298 | /** 299 | * truncate table 300 | * 301 | * @param string $table table name 302 | */ 303 | public function truncate($table) 304 | { 305 | $stmt = $this->run("TRUNCATE TABLE $table"); 306 | 307 | return $stmt->rowCount(); 308 | } 309 | } 310 | --------------------------------------------------------------------------------