https://github.com/mpyw/unclosure
Closure unwrapper especially suited for Laravel PDO.
https://github.com/mpyw/unclosure
closure laravel pdo php
Last synced: 8 days ago
JSON representation
Closure unwrapper especially suited for Laravel PDO.
- Host: GitHub
- URL: https://github.com/mpyw/unclosure
- Owner: mpyw
- License: mit
- Created: 2020-01-17T09:40:30.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2025-03-04T06:46:22.000Z (about 2 months ago)
- Last Synced: 2025-04-19T03:44:47.323Z (11 days ago)
- Topics: closure, laravel, pdo, php
- Language: PHP
- Homepage:
- Size: 29.3 KB
- Stars: 0
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Unclosure [](https://github.com/mpyw/unclosure/actions) [](https://coveralls.io/github/mpyw/unclosure?branch=master)
Closure unwrapper especially suited for Laravel PDO.
## Requirements
| Package | Version | Mandatory |
|:---|:----------------------|:---:|
| PHP |^8.2
| ✅ |
| PHPStan |>=2.0
| |> [!NOTE]
> Older versions have outdated dependency requirements. If you cannot prepare the latest environment, please refer to past releases.## Installing
```bash
composer require mpyw/unclosure
```# Examples
## Call `PDO::setAttribute()` after database connection has been established
```php
setAttribute(PDO::ATTR_EMULATE_PREPARES, $enabled);
return $pdo;
}$connector = function (string $dsn) {
return new PDO($dsn);
};// Eager Evaluation
$pdo = Value::withCallback($connector('sqlite::memory:'), 'withEmulation', true);// Lazy Evaluation
$pdo = Value::withCallback($connector, 'withEmulation', true);
$pdo = $pdo('sqlite::memory:');
```## Temporarily change `PDO` attributes
```php
getAttribute(PDO::ATTR_EMULATE_PREPARES);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, $enabled);
return function (PDO $pdo) use ($original) {
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, $original);
};
},
$callback,
...$args
);
}$connector = function (string $dsn) {
return new PDO($dsn);
};// Eager Evaluation
$pdo = $connector('sqlite::memory:');
switchingEmulationTo(true, $pdo, function () use ($pdo) {
// Run queries that require prepared statement emulation
});// Lazy Evaluation
$pdo = $connector;
switchingEmulationTo(true, $pdo, function () use (&$pdo) {
$pdo = $pdo('sqlite::memory:');
// Run queries that require prepared statement emulation
});
```# API
## `Value::withCallback()`
```php
static mixed|Closure withCallback(mixed|Closure $value, callable $callback, mixed ...$args)
```Call `$callback($value, ...$args)` or wrap its call into `Closure`.
- When you pass `$value` as `Closure`:
- Return wrapped `Closure` which returns **`$callback($value(), ...$args)`**.
- When you pass `$value` as a raw value:
- Return **`$callback($value, ...$args)`**.### Arguments and Return Value
| Name | Type | Description |
|:---|:---|:---|
|`$value`|mixed
(A) `Closure`|**First** argument for `$callback` which is unwrappable|
|`$callback`|(B) callable|A callback which takes **unwrapped `$value`** as the first argument|
|`...$args`|mixed|**Second, third, ...** arguments for `$callback`|
|<Return Value> |mixed
(C) `Closure`|Decorated `Closure` or an unwrapped value|#### (A) `$value`
```php
$value(mixed ...$initialArgs): mixed
```| Name | Type | Description |
|:---|:---|:---|
|`...$initialArgs`|mixed|Arguments for unwrapping `Closure`|
| <Return Value> |mixed|An unwrapped value|#### (B) `$callback`
```php
$callback(mixed $value, ...$args): mixed
```| Name | Type | Description |
|:---|:---|:---|
|`$value`|mixed|An **unwrapped** value|
|`...$args`|mixed|Arguments from `Value::withCallback()`|
| <Return Value> |mixed|A decorated unwrapped value|#### (C) Return Value
```php
*(mixed ...$initialArgs): mixed
```| Name | Type | Description |
|:---|:---|:---|
|`...$initialArgs`|mixed|Arguments for unwrapping `$value`|
| <Return Value> |mixed|An unwrapped value which is propagated from `$value(...$initialArgs)`|## `Value::withEffect()`
`Value::withEffectForEach()````php
public static withEffect(mixed|Closure &$value, callable $configurator, callable $callback, mixed ...$args): mixed
public static withEffectForEach((mixed|Closure)[] &$values, callable $configurator, callable $callback, mixed ...$args): mixed
```Call `$callback(...$args)`, watching new assignment on `&$value`. **You can conditionally unwrap `$value` in your `$callback` by yourself.**
- When you pass `$value` as `Closure`:
- If `$value` has been unwrapped, configurations via `$configurator` are applied.
- **If `$value` still remains as `Closure`, all configurations are canceled.**
- When you pass `$value` as a raw value:
- Configurations via `$conigurator` are immediately applied.### Arguments and Return Value
| Name | Type | Description |
|:---|:---|:---|
|`&$value`|mixed
(A) `Closure`|An argument for `$configurator` which is unwrappable|
|`$configurator`|(B) callable|A configurator callback which takes **unwrapped `$value`** as the first argument|
|`$callback`|(D) callable|Any callback function|
|`...$args`|mixed|Arguments for `$callback`|
| <Return Value> |mixed|Return value from `$callback(...$args)`|#### (A) `&$value`
```php
*(): mixed
```| Name | Type | Description |
|:---|:---|:---|
| <Return Value> |mixed|An unwrapped value|#### (B) `$configurator`
```php
$configurator(mixed $value): ?callable
```| Name | Type | Description |
|:---|:---|:---|
| `mixed` |mixed|An **unwrapped** value|
| <Return Value> |null
(C) callable|An optional disposer function corresponding to the configurator|#### (C) `$configurator` Return Value
```php
*(mixed $value): void
```| Name | Type | Description |
|:---|:---|:---|
| `mixed` |mixed|An **unwrapped** value|#### (D) `$callback`
```php
$callback(...$args): mixed
```| Name | Type | Description |
|:---|:---|:---|
|`...$args`|mixed|Arguments from `Value::withEffect()`|
| <Return Value> |mixed||