Hi Seifeddine, Tim,
I'm in favor of a feature similar to those listed in the RFC (Python’s
`with` [1], C#’s `using` [2], Hack's `using` [6]), but the proposal is not
equivalent to these. There are major differences that prevent it from
addressing the same use-cases.
First, the RFC proposes that variables are only unset() when leaving the
block, while Python, C#, Hack, and Java-s' try-with [3] (which is not
cited, but is similar), also immediately "close" or "dispose" of the
resource/object when leaving the block. This is important, as there are a
number of cases in which unset() alone will not immediately call a
destructor or close a resource.
Then, at least in Python, disposal is made aware of exceptions, so that it
can take different steps in that case.
The proposal relies on destructors or automatic closing of resources, but
this should not be relied on when timing matters. In general, destructors
should be avoided IMHO [4][5]. They are useful in languages with
stack-allocated variables because timing and order can be guaranteed, but
not in heap-allocated languages with automatic GC. PHP resources/objects
are heap-allocated, and its GC mechanism behavior/semantics is similar to
Java's due to cycles: resource/objects are not guaranteed to be
closed/disposed of immediately, and the order in which this happens is
undefined.
Here are some use-cases that Python's `with`, C#'s `using`, or Java's
`try-with` were designed to address, but are not addressed by this RFC:
// Commit the transaction as soon as the block is left, or roll it back if
an exception is thrown:
with ($db->beginTransaction() as $transaction) {
$transaction->execute(...);
$transaction->execute(...);
}
If $transaction escapes, it's not committed at the end of the block.
Regardless, it's not possible to automatically rollback the transaction in
case of exception.
// Close file descriptor as soon as the block is left:
with (get_fd() as $fd) {
// ...
}
If $fd escapes, it's not closed at the end of the block. This may affect
the program's behavior is various ways:
* The system's file descriptor limit may be reached before the GC triggers
* If $fd was a socket, and the other side waits for closing, it may hang
* If $fd has unflushed writes, readers will have an inconsistent view
// Await Scope at end of block:
with (new Async\Scope() as $scope) {
// ...
}
Again, if $scope escapes, it's not awaited at the end of the block, and
it's not possible to automatically cancel in case of exception.
Escaping/capturing is difficult to avoid, especially in large code bases,
as it can not be checked with static analysis, typing, or avoided by means
of API design. Sometimes it's even necessary, e.g. a file descriptor may be
referenced by an I/O polling mechanism.
> The RFC proposes the `use` keyword. What are your thoughts on a new
`using` keyword instead, similar to C# or Hack?
A possible alternative that doesn't introduce a new keyword is Java's try
() syntax.
> How do you feel about the questions raised in the "Open Issues" section?
I would prefer Option B (Restore), as this is what I would expect from
block scoping.
> Introducing a Disposable interface (similar to C#'s IDisposable) to allow
objects to define custom, explicit cleanup logic that is automatically
called by use.
I'm in favor of introducing this immediately, for the reasons above, and
also because introducing this later would make it difficult to adopt the
interface (implementing IDisposable on an existing class breaks existing
code using it in use()). I have a preference for Python's interface, as it
allows to optionally decouple (and hide) the dispose logic from the
resource, makes it possible to trigger a different behavior on exception,
and also makes it easier to introduce disposables without breaking code.
Also, making the interface optional, such that use($foo) is allowed when
$foo does not implement it, may mask programming mistakes and make the
feature confusing.
[1] https://peps.python.org/pep-0343/
[2]
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/statements/using
[3]
https://docs.oracle.com/javase/8/docs/technotes/guides/language/try-with-resources.html
[4] https://externals.io/message/125696#125710
[5] https://openjdk.org/jeps/421
[6] https://docs.hhvm.com/hack/statements/using
Best Regards,
Arnaud
On Mon, Nov 3, 2025 at 10:47 PM Seifeddine Gmati <[email protected]>
wrote:
> Hello internals,
>
> Tim and I would like to open the discussion on our new RFC that we've been
> working on: "use construct (Block Scoping)".
>
> We wanted to raise a few initial points:
>
> -
>
> The RFC proposes the `use` keyword. What are your thoughts on a new `
> using` keyword instead, similar to C# or Hack?
> -
>
> How do you feel about the questions raised in the "Open Issues"
> section?
> -
>
> What are your general thoughts on the RFC?
>
> Please find the following resources for your reference:
>
> -
>
> RFC: https://wiki.php.net/rfc/optin_block_scoping
> -
>
> POC:
>
> https://github.com/php/php-src/compare/master...TimWolla:php-src:block-scope
>
> Thanks,
>
> Seifeddine Gmati.
>
>