> Le 6 mai 2026 à 22:09, Bob Weinand <[email protected]> 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