Is it possible to add asynchronous loop call function ?

php.internals

€– ”k”k

2 years ago
Similar to a tick event, an async function will be called automatically after the block of code . and the async function is cleared when script shutown. Async function can be cleared after they have returned, or they can continue to be called at the next event after they have returned. and some of the features of Fiber

Daniil Gentili

2 years ago
Hi, You probably want something similar to golang's defer keyword. I intend to submit an RFC and PR for a defer keyword in PHP sometime in the future. Regards, Daniil Gentili.

Robert Landers

2 years ago
On Mon, Nov 20, 2023 at 10:06 AM chopins xiao <chopins.xiao@gmail.com> wrote:
> > Similar to a tick event, an async function will be called automatically after the block of code . > and the async function is cleared when script shutown. > Async function can be cleared after they have returned, or they can continue to be called at the next event after they have returned. > and some of the features of Fiber >
I think you want a flattened try { // do stuff } finally { // clean up } You can also emulate this with: class Defer { private function __construct(private \Closure $callback) {} public function __destruct() { $this->callback(); } public static function _(\Closure $callback) { return new self($callback); } } and use it like: function writeSomeStuff() { // open files $deferred = Defer::_($closeFiles(...)); // do stuff } So long as a reference exists to $deferred variable, the deferred method won't be run. If the variable is local to the method/function being run it, the deconstructor will be called after the function returns. It isn't the most beautiful thing in the world, and easy to forget to store the result of Defer, but it is handy sometimes. Robert Landers Software Engineer Utrecht NL

Michał Brzuchalski

2 years ago
Hi Robert, pt., 24 lis 2023 o 10:24 Robert Landers <landers.robert@gmail.com> napisał(a):
> ... > You can also emulate this with: > > class Defer { > private function __construct(private \Closure $callback) {} > public function __destruct() { $this->callback(); } > public static function _(\Closure $callback) { return new > self($callback); } > } > > and use it like: > > function writeSomeStuff() { > // open files > $deferred = Defer::_($closeFiles(...)); > // do stuff > } > > So long as a reference exists to $deferred variable, the deferred > method won't be run. If the variable is local to the method/function > being run it, the deconstructor will be called after the function > returns. > > It isn't the most beautiful thing in the world, and easy to forget to > store the result of Defer, but it is handy sometimes. >
This is interesting which makes me thinking if forget to store it could be prevented. I think requiring a ref could help with that: class Defer { private function __construct(private \Closure $callback) {} public function __destruct() { ($this->callback)(); } public static function _(\Closure $callback, &$var) { $var = new self($callback); } } $deferred = Defer::_($closeFiles(...), $foo); Without $foo there'd be an ArgumentCountError. Cheers, Michał Marcin Brzuchalski

Robert Landers

2 years ago
On Fri, Nov 24, 2023 at 11:27 AM Michał Marcin Brzuchalski <michal.brzuchalski@gmail.com> wrote:
> > Hi Robert, > > pt., 24 lis 2023 o 10:24 Robert Landers <landers.robert@gmail.com> napisał(a): >> >> ... >> You can also emulate this with: >> >> class Defer { >> private function __construct(private \Closure $callback) {} >> public function __destruct() { $this->callback(); } >> public static function _(\Closure $callback) { return new self($callback); } >> } >> >> and use it like: >> >> function writeSomeStuff() { >> // open files >> $deferred = Defer::_($closeFiles(...)); >> // do stuff >> } >> >> So long as a reference exists to $deferred variable, the deferred >> method won't be run. If the variable is local to the method/function >> being run it, the deconstructor will be called after the function >> returns. >> >> It isn't the most beautiful thing in the world, and easy to forget to >> store the result of Defer, but it is handy sometimes. > > > This is interesting which makes me thinking if forget to store it could be prevented. > I think requiring a ref could help with that: > > class Defer { > private function __construct(private \Closure $callback) {} > public function __destruct() { ($this->callback)(); } > public static function _(\Closure $callback, &$var) { $var = new self($callback); } > } > > $deferred = Defer::_($closeFiles(...), $foo); > > Without $foo there'd be an ArgumentCountError. > > Cheers, > Michał Marcin Brzuchalski
Hey Michael, Thinking about it some more, I think we can go even further than that and actually implement defer (enjoying the code golf)! function defer(mixed &$anchor, \Closure $deferred): void { if(is_resource($anchor)) { $anchor = new class($anchor) { public function __construct(public readonly mixed $resource) {} }; } static $mapping = new WeakMap(); $mapping[$anchor] = new class($deferred) { public function __construct(private \Closure $deferred) {} public function __destruct() { ($this->deferred)(); } }; } function writeFiles() { $handle = fopen("/tmp/scratch.php", "wb"); // todo: write data defer($handle, static function() use ($handle) { echo "\ndeferred\n"; fclose($handle); }); echo "\nafter defer()\n"; } writeFiles(); echo "\nafter writeFiles()\n"; or something like that.

Daniil Gentili

2 years ago
Hi,
> Thinking about it some more, I think we can go even further than that > and actually implement defer (enjoying the code golf)!
Dropping this here, just in case :) https://github.com/php-defer/php-defer From the posts on this thread (and the star count on php-defer), it seems there is indeed some interest in a defer keyword for PHP, might actually get to writing an RFC implementing the keyword itself this weekend... Regards, Daniil Gentili.