mirror of
https://codeberg.org/vlw/php-mysql.git
synced 2025-09-14 08:43:40 +02:00
Squashed commit of the following:
commite65c74797b
Author: Victor Westerlund <victor@vlw.se> Date: Thu Jan 30 08:16:27 2025 +0000 feat: add ORDER BY statement Enum (#41) Importable with: ```php use vlw\MySQL\Order ``` To be used with the `MySQL->order()` method, for example: ```php $db->for("table")->order(["column" => Order::ASC])->select("*"); ``` Reviewed-on: https://codeberg.org/vlw/php-mysql/pulls/41 commit64c7bae3cf
Author: Victor Westerlund <victor@vlw.se> Date: Thu Jan 16 13:53:30 2025 +0000 feat: add protected array property for where statement columns (#40) This PR adds a compliment for the `MySQL->filter_values` property but for filter columns which can be accessed from a protected scope with `MySQL->filter_columns` Reviewed-on: https://codeberg.org/vlw/php-mysql/pulls/40 commitd5f1efb9b9
Author: Victor Westerlund <victor@vlw.se> Date: Fri Dec 20 10:59:02 2024 +0000 feat: expose SQL class properties to protected scope (#39) Makes sense to make these accessible when extending the MySQL class. Reviewed-on: https://codeberg.org/vlw/php-mysql/pulls/39 commit619f43b3bf
Author: vlw <victor@vlw.se> Date: Wed Sep 25 13:28:15 2024 +0000 fix(doc): remove reference to removed method `flatten()` from README (#38) Closes #14 Reviewed-on: https://codeberg.org/vlw/php-mysql/pulls/38 Co-authored-by: vlw <victor@vlw.se> Co-committed-by: vlw <victor@vlw.se> commit1727247fa7
Author: vlw <victor@vlw.se> Date: Wed Sep 25 13:27:55 2024 +0000 fix: remove `where()` method for database models (#37) This PR removes the `where()` method which I don't think is particularly useful and also very untested since I don't use it personally at all. It's also probably better to do in-model checking for table columns **before** sending it off to this library when required anyways. Reviewed-on: https://codeberg.org/vlw/php-mysql/pulls/37 Co-authored-by: vlw <victor@vlw.se> Co-committed-by: vlw <victor@vlw.se> commita536a3bec4
Author: vlw <victor@vlw.se> Date: Wed Sep 25 13:27:20 2024 +0000 chore: rename of this package to "php-mysql" (#36) The name I gave this years ago "libmysqldriver" never sat right with me.. okay it might be considered a library for mysql but it's *definitely* not a driver. Reviewed-on: https://codeberg.org/vlw/php-mysql/pulls/36 Co-authored-by: vlw <victor@vlw.se> Co-committed-by: vlw <victor@vlw.se>
This commit is contained in:
parent
1da21b4b33
commit
78887576ef
5 changed files with 24 additions and 124 deletions
44
README.md
44
README.md
|
@ -1,11 +1,10 @@
|
||||||
# php-libmysqldriver
|
# php-mysql
|
||||||
|
|
||||||
This library provides abstraction methods for common operations on MySQL-like databases like `SELECT`, `UPDATE`, and `INSERT` using method chaining for the various MySQL features.
|
This is a simple abstraction library for MySQL DML operations.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
```php
|
```php
|
||||||
MySQL->for(string $table)
|
MySQL->for(string $table)
|
||||||
->with(?array $model)
|
|
||||||
->where(?array ...$conditions)
|
->where(?array ...$conditions)
|
||||||
->order(?array $order_by)
|
->order(?array $order_by)
|
||||||
->limit(int|array|null $limit)
|
->limit(int|array|null $limit)
|
||||||
|
@ -17,16 +16,16 @@ SELECT $columns FROM $table WHERE $filter ORDER BY $order_by LIMIT $limit;
|
||||||
```
|
```
|
||||||
|
|
||||||
> [!IMPORTANT]
|
> [!IMPORTANT]
|
||||||
> This library is built on top of the PHP [`MySQL Improved`](https://www.php.net/manual/en/book.mysqli.php) extension and requires PHP 8.0 or newer.
|
> This library requires the [`MySQL Improved`](https://www.php.net/manual/en/book.mysqli.php) extension and requires PHP 8.0 or newer.
|
||||||
|
|
||||||
## Install from composer
|
## Install from composer
|
||||||
|
|
||||||
```
|
```
|
||||||
composer require victorwesterlund/libmysqldriver
|
composer require vlw/mysql
|
||||||
```
|
```
|
||||||
|
|
||||||
```php
|
```php
|
||||||
use libmysqldriver/MySQL;
|
use vlw\MySQL\MySQL;
|
||||||
```
|
```
|
||||||
|
|
||||||
# Example / Documentation
|
# Example / Documentation
|
||||||
|
@ -53,7 +52,7 @@ id|beverage_type|beverage_name|beverage_size
|
||||||
3|tea|black|15
|
3|tea|black|15
|
||||||
|
|
||||||
```php
|
```php
|
||||||
use libmysqldriver\MySQL;
|
use vlw\MySQL\MySQL;
|
||||||
|
|
||||||
// Pass through: https://www.php.net/manual/en/mysqli.construct.php
|
// Pass through: https://www.php.net/manual/en/mysqli.construct.php
|
||||||
$db = new MySQL($host, $user, $pass, $db);
|
$db = new MySQL($host, $user, $pass, $db);
|
||||||
|
@ -108,24 +107,6 @@ $beverages = MySQL->for("beverages")->select(["beverage_name", "beverage_size"])
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Flatten array to single dimension
|
|
||||||
|
|
||||||
If you don't want an array of arrays and would instead like to access each key value pair directly. Chain the `MySQL->flatten()` anywhere before `MySQL->select()`.
|
|
||||||
This will return the key value pairs of the first entry directly.
|
|
||||||
|
|
||||||
> **Note**
|
|
||||||
> This method will not set `LIMIT 1` for you. It is recommended to chain `MySQL->limit(1)` anywhere before `MySQL->select()`. [You can read more about it here](https://github.com/VictorWesterlund/php-libmysqldriver/issues/14)
|
|
||||||
|
|
||||||
```php
|
|
||||||
$coffee = MySQL->for("beverages")->limit(1)->flatten()->select(["beverage_name", "beverage_size"]); // SELECT beverage_name, beverage_size FROM beverages WHERE beverage_type = "coffee" LIMIT 1
|
|
||||||
```
|
|
||||||
```php
|
|
||||||
[
|
|
||||||
"beverage_name" => "cappuccino",
|
|
||||||
"beverage_size" => 10
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
# INSERT
|
# INSERT
|
||||||
|
|
||||||
Chain `MySQL->insert()` anywhere after a [`MySQL->for()`](#for) to append a new row to a database table.
|
Chain `MySQL->insert()` anywhere after a [`MySQL->for()`](#for) to append a new row to a database table.
|
||||||
|
@ -330,9 +311,6 @@ MySQL->limit(
|
||||||
): self;
|
): self;
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Note**
|
|
||||||
> You can also flatten to a single dimensional array from the first entity by chaining [`MySQL->flatten()`](#flatten-array-to-single-dimension)
|
|
||||||
|
|
||||||
## Passing a single integer argument
|
## Passing a single integer argument
|
||||||
This will simply `LIMIT` the results returned to the integer passed
|
This will simply `LIMIT` the results returned to the integer passed
|
||||||
|
|
||||||
|
@ -367,13 +345,3 @@ $coffee = MySQL->for("beverages")->limit(3, 2)->select(["beverage_name", "bevera
|
||||||
// ...etc
|
// ...etc
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
# Restrict affected/returned database columns to table model
|
|
||||||
|
|
||||||
Chain and pass an array to `MySQL->with()` before a `select()`, `update()`, or `insert()` method to limit which columns will be returned/affected. It will use the **values** of the array so it can be either sequential or associative.
|
|
||||||
|
|
||||||
**This method will cause `select()`, `update()`, and `insert()` to ignore any columns that are not present in the passed table model.**
|
|
||||||
|
|
||||||
You can remove an already set table model by passing `null` to `MySQL->with()`
|
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
{
|
{
|
||||||
"name": "victorwesterlund/libmysqldriver",
|
"name": "vlw/mysql",
|
||||||
"description": "Abstraction library for common mysqli features",
|
"description": "Abstraction library for common MySQL/MariaDB DML operations with php-mysqli",
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"license": "GPL-3.0-only",
|
"license": "GPL-3.0-or-later",
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
"name": "Victor Westerlund",
|
"name": "Victor Westerlund",
|
||||||
"email": "victor.vesterlund@gmail.com"
|
"email": "victor@vlw.se"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"minimum-stability": "dev",
|
"minimum-stability": "dev",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"libmysqldriver\\": "src/"
|
"vlw\\MySQL\\": "src/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"require": {}
|
"require": {}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace libmysqldriver;
|
namespace vlw\MySQL;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
|
|
||||||
|
@ -8,25 +8,22 @@
|
||||||
use mysqli_stmt;
|
use mysqli_stmt;
|
||||||
use mysqli_result;
|
use mysqli_result;
|
||||||
|
|
||||||
use libmysqldriver\Order;
|
use vlw\MySQL\Operators;
|
||||||
use libmysqldriver\Operators;
|
|
||||||
|
|
||||||
require_once "Order.php";
|
require_once "Order.php";
|
||||||
require_once "Operators.php";
|
require_once "Operators.php";
|
||||||
|
|
||||||
// Interface for MySQL_Driver with abstractions for data manipulation
|
// Interface for MySQL_Driver with abstractions for data manipulation
|
||||||
class MySQL extends mysqli {
|
class MySQL extends mysqli {
|
||||||
private string $table;
|
|
||||||
private ?array $model = null;
|
|
||||||
|
|
||||||
private ?string $limit = null;
|
|
||||||
private ?string $order_by = null;
|
|
||||||
private array $filter_values = [];
|
|
||||||
private ?string $filter_sql = null;
|
|
||||||
|
|
||||||
// Array of last SELECT-ed columns
|
|
||||||
public ?array $columns = null;
|
public ?array $columns = null;
|
||||||
|
|
||||||
|
protected string $table;
|
||||||
|
protected ?string $limit = null;
|
||||||
|
protected ?string $order_by = null;
|
||||||
|
protected array $filter_columns = [];
|
||||||
|
protected array $filter_values = [];
|
||||||
|
protected ?string $filter_sql = null;
|
||||||
|
|
||||||
// Pass constructor arguments to driver
|
// Pass constructor arguments to driver
|
||||||
function __construct() {
|
function __construct() {
|
||||||
parent::__construct(...func_get_args());
|
parent::__construct(...func_get_args());
|
||||||
|
@ -61,14 +58,6 @@
|
||||||
return array_map(fn(mixed $v): string => "`{$v}`", $input);
|
return array_map(fn(mixed $v): string => "`{$v}`", $input);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return value(s) that exist in $this->model
|
|
||||||
private function in_model(string|array $columns): ?array {
|
|
||||||
// Place string into array
|
|
||||||
$columns = is_array($columns) ? $columns : [$columns];
|
|
||||||
// Return columns that exist in table model
|
|
||||||
return array_filter($columns, fn($col): string => in_array($col, $this->model));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
# Definers
|
# Definers
|
||||||
These methods are used to build an SQL query by chaining methods together.
|
These methods are used to build an SQL query by chaining methods together.
|
||||||
|
@ -86,35 +75,12 @@
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restrict query to array of column names
|
|
||||||
public function with(?array $model = null): self {
|
|
||||||
// Remove table model if empty
|
|
||||||
if (!$model) {
|
|
||||||
$this->model = null;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset table model
|
|
||||||
$this->model = [];
|
|
||||||
|
|
||||||
foreach ($model as $k => $v) {
|
|
||||||
// Column values must be strings
|
|
||||||
if (!is_string($v)) {
|
|
||||||
throw new Exception("Key {$k} must have a value of type string");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append column to model
|
|
||||||
$this->model[] = $v;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a WHERE statement from filters
|
// Create a WHERE statement from filters
|
||||||
public function where(?array ...$conditions): self {
|
public function where(?array ...$conditions): self {
|
||||||
// Unset filters if null was passed
|
// Unset filters if null was passed
|
||||||
if ($conditions === null) {
|
if ($conditions === null) {
|
||||||
$this->filter_sql = null;
|
$this->filter_sql = null;
|
||||||
|
$this->filter_columns = null;
|
||||||
$this->filter_values = null;
|
$this->filter_values = null;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -134,9 +100,7 @@
|
||||||
|
|
||||||
// Create SQL string and append values to array for prepared statement
|
// Create SQL string and append values to array for prepared statement
|
||||||
foreach ($condition as $col => $operation) {
|
foreach ($condition as $col => $operation) {
|
||||||
if ($this->model && !$this->in_model($col)) {
|
$this->filter_columns[] = $col;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assume we want an equals comparison if value is not an array
|
// Assume we want an equals comparison if value is not an array
|
||||||
if (!is_array($operation)) {
|
if (!is_array($operation)) {
|
||||||
|
@ -237,11 +201,6 @@
|
||||||
// Create array of columns from CSV
|
// Create array of columns from CSV
|
||||||
$this->columns = is_array($columns) || is_null($columns) ? $columns : explode(",", $columns);
|
$this->columns = is_array($columns) || is_null($columns) ? $columns : explode(",", $columns);
|
||||||
|
|
||||||
// Filter columns that aren't in the model if defiend
|
|
||||||
if ($columns && $this->model) {
|
|
||||||
$columns = $this->in_model($this->columns);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create CSV from columns or default to SQL NULL as a string
|
// Create CSV from columns or default to SQL NULL as a string
|
||||||
$columns_sql = $this->columns ? implode(",", self::array_wrap_accents($this->columns)) : "NULL";
|
$columns_sql = $this->columns ? implode(",", self::array_wrap_accents($this->columns)) : "NULL";
|
||||||
|
|
||||||
|
@ -264,16 +223,6 @@
|
||||||
public function update(array $entity): mysqli_result|bool {
|
public function update(array $entity): mysqli_result|bool {
|
||||||
$this->throw_if_no_table();
|
$this->throw_if_no_table();
|
||||||
|
|
||||||
// Make constraint for table model if defined
|
|
||||||
if ($this->model) {
|
|
||||||
foreach (array_keys($entity) as $col) {
|
|
||||||
// Throw if column in entity does not exist in defiend table model
|
|
||||||
if (!in_array($col, $this->model)) {
|
|
||||||
throw new Exception("Column key '{$col}' does not exist in table model");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create CSV string with Prepared Statement abbreviations from length of fields array.
|
// Create CSV string with Prepared Statement abbreviations from length of fields array.
|
||||||
$changes = array_map(fn($column) => "`{$column}` = ?", array_keys($entity));
|
$changes = array_map(fn($column) => "`{$column}` = ?", array_keys($entity));
|
||||||
$changes = implode(",", $changes);
|
$changes = implode(",", $changes);
|
||||||
|
@ -298,11 +247,6 @@
|
||||||
public function insert(array $values): mysqli_result|bool {
|
public function insert(array $values): mysqli_result|bool {
|
||||||
$this->throw_if_no_table();
|
$this->throw_if_no_table();
|
||||||
|
|
||||||
// A value for each column in table model must be provided
|
|
||||||
if ($this->model && count($values) !== count($this->model)) {
|
|
||||||
throw new Exception("Values length does not match columns in model");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Use array keys from $values as columns to insert if array is associative.
|
Use array keys from $values as columns to insert if array is associative.
|
||||||
Treat statement as an all-columns INSERT if the $values array is sequential.
|
Treat statement as an all-columns INSERT if the $values array is sequential.
|
||||||
|
@ -324,18 +268,6 @@
|
||||||
public function delete(array ...$conditions): mysqli_result|bool {
|
public function delete(array ...$conditions): mysqli_result|bool {
|
||||||
$this->throw_if_no_table();
|
$this->throw_if_no_table();
|
||||||
|
|
||||||
// Make constraint for table model if defined
|
|
||||||
if ($this->model) {
|
|
||||||
foreach ($conditions as $condition) {
|
|
||||||
foreach (array_keys($condition) as $col) {
|
|
||||||
// Throw if column in entity does not exist in defiend table model
|
|
||||||
if (!in_array($col, $this->model)) {
|
|
||||||
throw new Exception("Column key '{$col}' does not exist in table model");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set DELETE WHERE conditions from arguments
|
// Set DELETE WHERE conditions from arguments
|
||||||
$this->where(...$conditions);
|
$this->where(...$conditions);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace libmysqldriver;
|
namespace vlw\MySQL;
|
||||||
|
|
||||||
enum Operators: string {
|
enum Operators: string {
|
||||||
// Logical
|
// Logical
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace libmysqldriver;
|
namespace vlw\MySQL;
|
||||||
|
|
||||||
enum Order: string {
|
enum Order: string {
|
||||||
case ASC = "ASC";
|
case ASC = "ASC";
|
||||||
|
|
Loading…
Add table
Reference in a new issue