mpyw / unclosure
Closure unwrapper especially suited for Laravel PDO
Installs: 76 509
Dependents: 2
Suggesters: 0
Security: 0
Stars: 0
Watchers: 3
Forks: 1
Open Issues: 0
Requires
- php: ^7.4 || ^8.0
Requires (Dev)
- phpstan/phpstan: >=1.1
- phpunit/phpunit: >=9.5
README
Closure unwrapper especially suited for Laravel PDO.
Requirements
Installing
composer require mpyw/unclosure
Examples
Call PDO::setAttribute()
after database connection has been established
<?php use Mpyw\Unclosure\Value; use PDO; function withEmulation(PDO $pdo, bool $enabled): PDO { $pdo->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 use Mpyw\Unclosure\Value; use PDO; function switchingEmulationTo(bool $enabled, &$pdo, callable $callback, ...$args) { return Value::withEffect( $pdo, function (PDO $pdo) use ($enabled) { $original = $pdo->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()
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
asClosure
:- Return wrapped
Closure
which returns$callback($value(), ...$args)
.
- Return wrapped
- When you pass
$value
as a raw value:- Return
$callback($value, ...$args)
.
- Return
Arguments and Return Value
(A) $value
$value(mixed ...$initialArgs): mixed
(B) $callback
$callback(mixed $value, ...$args): mixed
(C) Return Value
*(mixed ...$initialArgs): mixed
Value::withEffect()
Value::withEffectForEach()
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
asClosure
:- If
$value
has been unwrapped, configurations via$configurator
are applied. - If
$value
still remains asClosure
, all configurations are canceled.
- If
- When you pass
$value
as a raw value:- Configurations via
$conigurator
are immediately applied.
- Configurations via
Arguments and Return Value
(A) &$value
*(): mixed
(B) $configurator
$configurator(mixed $value): ?callable
(C) $configurator
Return Value
*(mixed $value): void
(D) $callback
$callback(...$args): mixed