Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129761 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by lists.php.net (Postfix) with ESMTPS id 9525A1A00BC for ; Thu, 15 Jan 2026 18:39:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1768502348; bh=Ji2QJraizCS7RFDebm/gqIyZxh7vbgaJ378/7/FLnQw=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=IpPctT8lTB5h4eXHhvWNvu9xtlgOoQq4yDwXV2vwDRj7mfvVh5MgZ82ByFCCL6Q3m leQlzpTfmctas7J76E8gbXt2cajbOad4Z8sm6Du3raKhflRdfYQsptr8clu6F7HJTN CKlcFZkkLdxeBwez6XRT7cLMFsCbRJwDXgWbAUksWzUcdLTNuBnaCO/8LBU76B4x1Y I0aXbUymkFiHnqpM4dod/PXOYsW1IlgkZYTSfs+6Dl1qw9raa9tt6ZvMgnFXg774Hw KMaZGonIeV3mcS6067+NnMJK7jDCjGlDnaN7DKuQn4HfXmopqFGM/B6xqBiLWK5NR2 IsgSY+exXXYcA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 042ED1801D8 for ; Thu, 15 Jan 2026 18:39:08 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on php-smtp4.php.net X-Spam-Level: * X-Spam-Status: No, score=1.8 required=5.0 tests=BAYES_50,DMARC_NONE, FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from mail-pf1-f179.google.com (mail-pf1-f179.google.com [209.85.210.179]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Thu, 15 Jan 2026 18:39:07 +0000 (UTC) Received: by mail-pf1-f179.google.com with SMTP id d2e1a72fcca58-81dab89f286so599017b3a.2 for ; Thu, 15 Jan 2026 10:39:02 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768502341; x=1769107141; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=bZyphyE86XReRtgwtg9aNfdmZgUonx07GsL9kqLxiVw=; b=AD05uBExQJavfdfJCfeDdGDzqE1m5Vk3Pae1DpcPo5tHxR954rD8rC95YEZcrvu8RJ 8nDOFxO9r+h9RuzFGAq0keL7Q54FSC09Q4flL8+I61xq3AzmN6uSZARjb/6wj8a67MDk 9gozr4k4P3NSiBE7LM7HK07CeBjZdYjWzOgHdlXzcTK9OJ1yEl0GkDo8Nrguj/vf4rq3 QqxZOgJQOErsKTigwYVPgw6MKyBbfwRFfW6p6mZ4LeYrsDxcNcr3Z8gTPiCAIJuTqaCZ Mz9pwQgDfYq4HDSVeH8c0j0JOJQm3H5tCBkuLi0dZjVTHGUXxLdc5h23YLZYTPmjOpDh cEdA== X-Gm-Message-State: AOJu0YxWDH2dy4lm24OU6NBvfWf4gvWEnzlIJGTESz4PeHGk56kk7WWG 0amhLoP7rlpraNBzhWfEFPqpf1rX1y3QZFVSxcFc28/wdcUa/4ZxYdFrgO4I3w== X-Gm-Gg: AY/fxX6U9s7fmhn0aWXw5JdEV/v5FkDmHOYVNWBnTIQfRU39jIdHS6vk2+rE0q0pBB8 4x7FlV0bcJpFKAe1yYu/QAUHXq37dQQIHwKnOra08EPxB+KbJepP5fLgFcUd8DqCqQeK+kOZC9z IBNoR2/fugLCbfpLnpoozD4z3dgi8HpOgxi0OzSvwQDXT02rumbBlnXUvNwsSUAx3/a8XpSUNjm OnhACxXeS5SBIrdVHCMztZJ3kC/XF3iDgWR6FAkpg0pjD8Iq3ya8SYeBoj+152wWPDcTHwZAEWa PgEVAozBVBawR/GBJX/hqTQIeIbhTbhV43yMiriLp94BTiIyJQinEc/7x0FBsyoAF/LddZcW98O H8HfkuQ07XetMi0qgBWGWKoOl3pRnJ8ooIHtF58UhiJYHkdwIK4xOZ/9FV2ZRomJeN5KBFMorOW 37LfPlIqs8utZDplh9JkziOTEH5XgI3HQcFA0RvN7HpUX+8Q== X-Received: by 2002:a05:6a00:92a0:b0:817:9a85:54af with SMTP id d2e1a72fcca58-81fa01ebbf1mr484449b3a.43.1768502341332; Thu, 15 Jan 2026 10:39:01 -0800 (PST) Received: from mail-pg1-f176.google.com (mail-pg1-f176.google.com. [209.85.215.176]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-81fa1278056sm86747b3a.34.2026.01.15.10.39.00 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 15 Jan 2026 10:39:00 -0800 (PST) Received: by mail-pg1-f176.google.com with SMTP id 41be03b00d2f7-c551edc745eso609982a12.2 for ; Thu, 15 Jan 2026 10:39:00 -0800 (PST) X-Received: by 2002:a17:90a:d40d:b0:340:ec8f:82d8 with SMTP id 98e67ed59e1d1-35272ee18cfmr354432a91.12.1768502340228; Thu, 15 Jan 2026 10:39:00 -0800 (PST) Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 References: In-Reply-To: Date: Thu, 15 Jan 2026 19:38:46 +0100 X-Gmail-Original-Message-ID: X-Gm-Features: AZwV_QhIyZT0znboQN4uzXiweG5wlCQSch18HODn6X3lU8U2mtuvR0OFI0FJZY0 Message-ID: Subject: Re: [PHP-DEV] [RFC] Context Managers To: Larry Garfield Cc: php internals Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable From: edorian@php.net (Volker Dusch) On Tue, Nov 4, 2025 at 9:19=E2=80=AFPM Larry Garfield wrote: > > Arnaud and I would like to present another RFC for consideration: Context= Managers. > > https://wiki.php.net/rfc/context-managers > > You'll probably note that is very similar to the recent proposal from Tim= and Seifeddine. Both proposals grew out of casual discussion several mont= hs ago; I don't believe either team was aware that the other was also activ= ely working on such a proposal, so we now have two. C'est la vie. :-) > > Naturally, Arnaud and I feel that our approach is the better one. In par= ticular, as Arnaud noted in an earlier reply, __destruct() is unreliable if= timing matters. It also does not allow differentiating between a success = or failure exit condition, which for many use cases is absolutely mandatory= (as shown in the examples in the context manager RFC). > > The Context Manager proposal is a near direct port of Python's approach, = which is generally very well thought-out. However, there are a few open qu= estions as listed in the RFC that we are seeking feedback on. > > Discuss. :-) > > -- > Larry Garfield > larry@garfieldtech.com > Hi Larry, Hi Internals, Last year I promised you (Larry) some feedback on-list as well and didn't get around to it until now. I recognize the strain that repeating arguments has on a discussion like this, and this topic has already taken up a lot of focus and time for the folks here. But I wanted to at least explain why I think PHP would be better off without having this in core and why I think it would be a net negative for PHP to have this. So to summarize, I find the feature doesn't fit in PHP. It's introducing more magically called methods, burdened with unnecessary complexity, while being very limited in its potential (sensible) uses. Combined with its class-only high-verbosity approach, I feel this is lacking places where it would improve PHP code in general and better suited for a library for people that want this type of, what I consider, magical indirection. With the name also being extremely generic and non-descriptive, this all feels like bloat to me that complicates the language for no tangible benefits. To expand a bit on the points: - Non-local behavior: Every using statement is a couple of function calls that are non-obvious in how they delegate to some __magic interface methods that are not supposed to (but very able to) be called explicitly. With the implicit catch and exitContext() ability to return true/false; to rethrow/suppress an exception, adding even more hidden branching to execution. - Variable masking: A new block masking and restoring the context variables but not others is an additional source of errors and confusion that I feel doesn't pay off in terms of value vs. added complexity and error sources. It's not behavior we have anywhere else in PHP and breaks the flow of reading and reasoning about code in non-obvious ways. - Break/Continue semantics: There is no clear reason for me why this block scope should allow early returns. If the content is growing to a point where it's needed, a function is already a reasonable scope. Given that PHP allows for `break 2;`, something that we'll see more of then, it's manageable. It just adds to the, for me, unreasonable complexity of the feature. - Naming: For me, despite having worked with Python, the name means absolutely nothing. It doesn't even manage the context of the invocation. If anything, it manages when a resource is released into and removed and deallocated from a scoped context. And that sentence also is rough. PHP, for better or worse, doesn't burden its users with having to study many CS concepts beyond basic OO or procedural programming and still allows them to write obvious, valuable, and predictable code. I understand that with its evolution this has changed, and we have added a lot of redundancy (short arrays, short functions, pipes, etc..) to provide sugar that has steepened the learning curve for some. Adding very specific single-use concepts to the language with their own disconnected naming schemes, syntax, or, in this case, hidden behaviors should be carefully considered. And while I'm sure you did we came to different conclusions. - Block scoping: Personally, I don't see the need for block scoping in PHP in general. But having a generic solution that works without creating a new class for each case would feel like something that at least can be used by everyone and every part of the language. Tying this to custom objects doesn't feel like a language level feature but something that should be in a library. The worst option would be to allow using() to take a context manager or a plain expression and make people guess every time the statement is used if hidden function calls are attached to it. - Verbosity: Having to implement three code paths for each ContextManager (enter, exitWithoutError, exitWithError) within two functions, with a near mandatory `if` in a separate class, doesn't strike me as useful over patterns like getting and returning a connection out of a pool =E2=80=9Cmanually.=E2=80=9D The trade-off between this and already existing= solutions to this problem with try/finally or construct/destruct isn't enticing. - Object lifecycle in PHP: Just to reiterate because it bugs me as PHP zval life cycles are used as an argument here: Reference counting in PHP is fully deterministic, and code like `function () { $x =3D new Foo(); return; }` will deterministically construct and destruct (at the end of the function as the variable gets cleaned up). Use cases where the GC would actually come into play are extremely rare from the real-world usages we can see in Python. I also haven't seen an example in PHP nor something in the RFC that looks overly convincing in improving this with managed in-function unsets. The error handling option is nice, but for maintainability, simplicity, and effort in writing code, I'd still prefer this to try/(catch)/finally Layering another level of lifecycle management on top of the existing PHP behavior doesn't feel like a simplification but rather like another source of complexity with this new niece special case. -- In summary, this feels like beyond what's necessary to get rid of a couple of try/finally blocks per application and encourages bad patterns like using ContextMangers for async instead of more modern APIs that have evolved since then. Kind Regards, Volker