Re: [RFC] Scope functions

From: Date: Wed, 06 May 2026 22:26:33 +0000
Subject: Re: [RFC] Scope functions
References: 1  Groups: php.internals 
Request: Send a blank email to internals+get-130789@lists.php.net to get a copy of this message
> Le 6 mai 2026 à 22:09, Bob Weinand <bobwei9@hotmail.com> a écrit : > > Volker and I drafted a RFC: > > https://wiki.php.net/rfc/scope-functions > > Please consider it and share your feedback. > > I hope it will alleviate pain around some of the most common forms of Closure usage which is > "execute this now as part of the called function", which currently can require a lot of > "use ($variables)". > > For me the primary use case of use ($capturing) was always "I need this function later and > want to explicitly document what escapes my function". This, however, required this > straightforward usage of Closures to also document every single usage of a variable. Which is really > not that beneficial at all. > > Thus the scope functions as proposed will be able to fill that gap in future. > > Thank you, > Bob Hi, This is nice. As I understand it, this RFC could resolve problems that the Context Managers RFC tries to resolve in a simpler and more flexible way. (And it resolves other problems too, of course.) Taking the first example from the Context Manager RFC: ```php using (file_for_write('file.txt') => $fp) { foreach ($someThing as $value) { fwrite($fp, serialize($value)); } } // implementable as: function file_for_write(string $filename): ContextManager { return new class($filename) implements ContextManager { function __construct(private readonly string $filename) { } private $fp; function enterContext() { $this->fp = @fopen($this->filename, 'w'); if (!$this->fp) { throw new \RuntimeException('Couldn’t open file'); } return $this->fp; } function exitContext(?\Throwable $e = null): ?\Throwable { @fclose($this->fp); return $e; } }; } ``` This can be rewritten as: ```php file_for_write('file.txt', fn($fp) { foreach ($someThing as $value) { fwrite($fp, serialize($value)); } }); // implementable as (which is simpler: one function instead of a whole class): function file_for_write (string $filename, callable $do_write): void { $fp = @fopen($filename, 'w'); if (!$fp) { throw new \RuntimeException('Couldn’t open file'); } try { $do_write($fp); } finally { @fclose($fp); } } ``` For those of us that abhor exceptions in case of recoverable failure, there is even more. With this RFC, one can easily return true/false (or whatever other signal) for success/failure, while Context Manager strongly leans towards the use of exceptions (although, of course, it remains possible to assign the outcome to a variable and to exit the context with break or goto): ```php $ok = file_for_write('file.txt', fn($fp) { foreach ($someThing as $value) { if (something_is_wrong_with($value)) return false; fwrite($fp, serialize($value)); } return true; }); // implementable as (which is more flexible: exceptions are not the only type of signal): #[\NoDiscard] function file_for_write (string $filename, callable $do_write): bool { $fp = @fopen($filename 'w'); if (!$fp) { return false; } try { return $do_write($fp); } finally { @fclose($fp); } } ``` —Claude

« previous php.internals (#130789) next »