> 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



Reply via email to