antoksa / callable-that-proxy
Lightweight proxy to create a callable from a 'dynamic' object during runtime
Requires
- php: ^8.0
Requires (Dev)
- phpunit/phpunit: ^9.6
This package is not auto-updated.
Last update: 2025-06-20 06:59:51 UTC
README
"That" Philosophy
Lightweight proxy "that" provides ability to create a callable for an object during runtime.
The idea of "that" is to reference the way how you usually create a callable for particular object.
$this->method(...) # For particular object that()->method(...) # For an expected object which is about to be accessed during the loop
Concept
How often did you need to perform array_map()
like this?
array_map( static function (MyClass $object): string { return $object->method(); }, $objects, ); array_map( static fn (MyClass $object): string => $object->method(), $objects, ); array_map( static fn (MyClass $object): string => $object->method($arg1, $arg2), $objects, ); array_map( static fn (MyClass $object): string => $object->property, $objects, );
Unfortunately, even though we can create objects like [$this, 'method']
,
but we can't access the object during iteration for runtime (e.g. array_map()
, array_filter()
etc.)
Lightweight proxy "that" brings this handy feature:
array_map( that()->method(...), # static fn (MyClass $object): string => $object->method() $objects, ); array_map( that()->withArgs($arg1, $arg2)->method(...), # static fn (MyClass $object): string => $object->method($arg1, $arg2), $objects, ); array_map( that()->property, # static fn (MyClass $object): string => $object->property $objects, );
Usage
Basic
### Call method [that(), 'method'] that()->method(...) that()->call('method') that(method: 'method') ### Add arguments [that()->withArgs($arg1, $arg2), 'method'] that()->withArgs($arg1, $arg2)->method(...) that()->call('method', [$arg1, $arg2]) [that(args: [$arg1, $arg2]), 'method'] that(args: [$arg1, $arg2])->method(...) ### Get Property that()->property that()->get('property') that(property: 'property')
Laravel Collection Advantage
Yes, Laravel got HighOrderedProxy
which allows to the chain of operations conveniently,
but IDE loses the type for it:
collect($objects) ->map ->method() # Return type is lost ->filter ->anotherMethod($arg1) ->all(); collect($objects) ->map ->existingCollectionMethodWhichReturnsBool() # Even worse, now IDE thinks that it returns bool here ->filter # Static analysis tools complains ->anotherMethod($arg1) ->all();
That's why I personally for this case would prefer to avoid HighOrderedProxy
.
It`s where "that" proxy comes handy:
collect($objects) ->map([that()->method(...)) ->filter(that()->withArgs($arg1)->anotherMethod(...)) ->all(); # Return type never gets lost
Note
First argument (class) is not required, however when provided, you take advantage of IDE autocompletion:
# Full support that(MyClass::class)->method(...) that()->setClass(MyClass::class)->method(...) that(MyClass::class)->property that()->setClass(MyClass::class)->property # Partial support; IDE does not suggest method, # but it`s clickable as soon as you type it [that(MyClass::class), 'method'] [that()->setClass(MyClass::class), 'method'] # No support; However, eventually, you never need that unless # you want to call method which exists in That class that(MyClass::class)->call('method') that(MyClass::class, method: 'method') that(MyClass::class)->get('property') that(MyClass::class, property: 'property')