Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129096 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 D6C481A00D1 for ; Wed, 5 Nov 2025 22:39:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1762382359; bh=5YepMKANDEv45vf2hfY+tej7FXftKEE8NTIks2KNosU=; h=Date:Subject:To:References:From:In-Reply-To:From; b=oN9buBOcP/9dYXR4d8VQ+hjcpdy3NAaqXcjacoEke3+1p06zXb/z/1bb5/mzivQMC FMqAvhzwByoaRQvK8MfGXvIICOkgl+3RZg+tjowjRTj+mxyISrNpHiLeksgg44TR3r 197bGu7Hwr14mFqsFnFJXFtLi1B/jNFS6NqhiqvAcaonwveX1P7jWP696Wayj3S//n +YjXBwR0hKKSaOzcnxs64D2xKdt1FAF3SjoUrg7wAZF0mZYsCXdiQJG0VOG4Rx3SSx MuGJHtw72YaCyTwC5IuX/1vtjgnTL9o7Zq+zvGvBgdzbfZPRMEGfCZzAo8MMFbty76 a5anDPPhuLv1Q== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id A59DC180082 for ; Wed, 5 Nov 2025 22:39:16 +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=0.9 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_50, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS, FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from DUZPR83CU001.outbound.protection.outlook.com (mail-northeuropeazolkn19012011.outbound.protection.outlook.com [52.103.32.11]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (secp384r1) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Wed, 5 Nov 2025 22:39:09 +0000 (UTC) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=PZocsjuQk+MBVpfXv85Q248hcG9AZbAiIEQpeqwc7ekxDIModDXYY8lh4mWqnCPi5q9LyqdrCXU22y8CRPhSPIMz/u/meZVSxDdCr5S/pji4ASgMAEG2JU4a7GbSKmXcgVdyEBkeqnGNEmIWlQjpgp4tj6lGg+PnsKiFy7Op3J4rD+ogX5vQnHtd7H1aNMCfL2Rgzvz1Au9tYwSksjI1lUSDaquuBW4crtUtMFgHkt7nPFjmZXfhLETPIrkId8qWrpQALiwbrpEOTVij7UNoHBoO/NnOBUFSlXG7gUoE/Mp3usPl6K3uTCWaMBaai3sEQ7qfowtnuCppiaFTPnMGdQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=nq1Zk3pSYGg0GkusRMLZM2NsYDjg5Ey+0TCpI1IJc4A=; b=Snr0uNcWRGqtiN5tLR6ipaggmcq4laGVmYU1U3PPOMmdaUXtFg8q8Vtmy2nkePGQvFqnAv8Io5HxegSMmd8NrdiQGzx++R5uMAb+6Vnit8ivVBAg9dhBj5/Amzrrv07cvni+ngazab7PrQPML2s1IADkvWu8qd/f1XKT7Ms8g3JwqrP7INomcvuHLtNFCD0rpgM5TNH3Cykmeq86oLyXzbV7bMl2zCxehcU3RAK+GFdxEtah5+DEUeZ7Sfajou36h2h6XhCYBfIs/vW+L6qIXLZe1i8J8erry3P0Ya3SsfzYnbCuPD2hjQfK7SjN/DyMTTtibNadqflHNszvjPEtOw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hotmail.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=nq1Zk3pSYGg0GkusRMLZM2NsYDjg5Ey+0TCpI1IJc4A=; b=P/7oc9F4m/iG0pAEoHLX9PNwnem26aSkehERvlH8jhWkyrsL5uYTn7/BnZECdmZshqkf+ELn4mpy9eie3yPO1KgxE638EJuQLUdwyfuo9x0OUk7ygMbAKzppANoZsdMAG9PWveZHoiJJF7hvlviU+yMD6IUZLN71OgL0biX8ZdzrQ0CpphQ6uGcAfzRP26tWQTC29sCBF4HuTUVHV7PPVnNpQP1huusIf/tN+t5JRz6jxQtGp2kqPamgrjHCcy7cW8hvzO8Zu0wlgItZftHGRMwuwgWn2rYJ/AtELtTiiQeG8hW7vm2qsfpC19i7qv9gewj/kuGGOYnlrfGfQq4UCw== Received: from AM8P250MB0170.EURP250.PROD.OUTLOOK.COM (2603:10a6:20b:321::21) by AM8P250MB0359.EURP250.PROD.OUTLOOK.COM (2603:10a6:20b:32a::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9275.16; Wed, 5 Nov 2025 22:39:01 +0000 Received: from AM8P250MB0170.EURP250.PROD.OUTLOOK.COM ([fe80::651e:bbd2:b18a:80ff]) by AM8P250MB0170.EURP250.PROD.OUTLOOK.COM ([fe80::651e:bbd2:b18a:80ff%3]) with mapi id 15.20.9298.006; Wed, 5 Nov 2025 22:38:59 +0000 Message-ID: Date: Wed, 5 Nov 2025 23:38:58 +0100 User-Agent: Mozilla Thunderbird Subject: Re: [PHP-DEV] [RFC] Context Managers To: Larry Garfield , php internals , =?UTF-8?Q?Tim_D=C3=BCsterhus?= , Arnaud Le Blanc , Seifeddine Gmati References: Content-Language: en-US In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-ClientProxiedBy: AS4P190CA0049.EURP190.PROD.OUTLOOK.COM (2603:10a6:20b:656::20) To AM8P250MB0170.EURP250.PROD.OUTLOOK.COM (2603:10a6:20b:321::21) X-Microsoft-Original-Message-ID: <4c9c497f-3df1-4531-85f2-aeba9ca79a03@hotmail.com> Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AM8P250MB0170:EE_|AM8P250MB0359:EE_ X-MS-Office365-Filtering-Correlation-Id: dce4ea08-f287-4ecd-c9ea-08de1cbc1c8c X-Microsoft-Antispam: BCL:0;ARA:14566002|461199028|6090799003|5072599009|15080799012|23021999003|12121999013|19110799012|8060799015|4302099013|3412199025|440099028|10035399007|40105399003|12091999003|26104999006|1602099012; X-Microsoft-Antispam-Message-Info: =?utf-8?B?Y2R5bDVqdENsTGd2ZjBlNjBtRkNiNkYxYkFQd0JOTFgyRDRmWWRyaDJOVmdo?= =?utf-8?B?WWFqNUM1OHdsZlBweUVtOTBLNnFMU0puS3loUGhVYzZnQVF6T0EwdmNzb2Z4?= =?utf-8?B?M3lXbWhjbnpnbzVEVmhKak1tTnA2OEF2V3ZnSjhZK3ZyRG91SUp4M3BLOW91?= =?utf-8?B?Y0w2QlNKb1ZPT3pXZHBYL0l6WFk0ZE5tZm5PSjlkc0pRaXB4Si9rS0wrSEpl?= =?utf-8?B?U3FBWm5aSGdIY3NaM0JzaHlzU1Q2VDk1bCs5U0RBWXkrWkJ1WnVnUTY4UWNX?= =?utf-8?B?YUd4M0xoVnRDMll4SDNTbDhlQmRyUHJ5SXRrS3UxWGo5R2dhWWxzQ0pkNnNi?= =?utf-8?B?K3poWEdiWm40SWluTXJXZmdNTENQaHVHbVErQWpIQ3YrUHpTU2dvWjdpWm80?= =?utf-8?B?d1B2STFOZHlDSW8xOUFDcGx2d3piUG82S3ZKcXBWQ1BUMGtrUTB5RG5BbXRz?= =?utf-8?B?aVZ0YmJ5Q2c2dDB3M0M1bURKY2JnblAxVmt0NzIrLytYR2NxTU5NV1dJVXN4?= =?utf-8?B?cllPTTZZMGN4aUJDM0hQQ2daamVucUR4UnNmMkljbTJHY2RFaUxsQ04vRlRz?= =?utf-8?B?SWpHc2h6WUw2cGpKWU1OaWhCanNWWTFlK3lDOHhPM2tTRzlKMFlnT1FXaWV3?= =?utf-8?B?NHhnRGZkUTlMNFNkVC9WdkFBNXBnR0VMSWRnd2FISTRpc00wUzdOWEdaaG84?= =?utf-8?B?bURjNmRENFBwazdTaVMwZ3hhUjFqeUMySFZLdDI2R0tkYm5EN0V4bUlUZlhm?= =?utf-8?B?YUZQM1daVUhsN1VFRjBlVWdaSHRubGlOY2EzdFBKSEo4Q0FyNmFheTRBN1VO?= =?utf-8?B?OENCeHpzVXRBWUJaQi9LYTJUT0dJNWpVaGcwTi9KY25zakcyYkNCMjVBeDlx?= =?utf-8?B?TW5KbnhNbUlURjlaR3ozdlN3K0N5dVBDNVBSVDF1VFdLWVVDaWVBZ2piVjdZ?= =?utf-8?B?TC9RNlgwNldOeEw1bG5mZjIwcngxdG9saXBsUmxRbk1yajAxbVAyWm8xMnVm?= =?utf-8?B?MXZnZEVWSHFQU3BGMjBmRmVyd2dFdEJ5V2lKZ2JTVS9OUzZ3WDliK2FUYzhB?= =?utf-8?B?SWRuQUwrTGtmd1pxeDdDdU4wdXgvZ0twNWRGSmtKOERoVTR6cmFPbC9UOWdq?= =?utf-8?B?aVU3RytFTzhxeGpCRUU3RFdFcm9HQ2pzRVpMcm1NeStCMVN0NENUcnY4S0dr?= =?utf-8?B?VnFmZHpVbVM2YVRsVDRTdDljemdkeXI2V1RRRy9zend5UGVnemtTVU9ub2xW?= =?utf-8?B?Z3RaMUJNa2RWWVBBUGpaOUJieG9vZDhiY1BYc1F1ZERWMGhVMDJYdGF5a2x6?= =?utf-8?B?VmFqbUZpa21GcFlrLzJMem9acmdEU0dXTmRVQ3NyUVhnL3lxbEdmTVFQNXVJ?= =?utf-8?B?RlRSWTlaVUtxN1BpeUZYZzVKSXlFdm5QaTd1c2MzdGk1b3hsRTBYUWwxSXJw?= =?utf-8?B?OENoYjBLVjZsNmZ2VlVEaWZmMFJ6N0pVZ1B5b09DWGhFNlNnU0RYcWNjcmw1?= =?utf-8?B?cFlvRE5EQ0xaNERmYnNzNTFrZHpGS29ZMXFid1MrRkttTWxvRk85M24zYWNB?= =?utf-8?B?KzRVMUJtWExqcEhvL1dVSUxQaXBadjhQSmExWlBRMWhpWmo0WS85MHNWdWl5?= =?utf-8?B?eUwvWlJEZ2dzQ3dGOWJUVUs2OUpqanFJSW9FaXNvcjF0dHFRMG1iVlQxdWR3?= =?utf-8?B?d3FLa3RjSnFURHVrdy9PYmh2RVJWMllMUitmNHZ0K0hwemhrL2tFUHBWbzMy?= =?utf-8?B?NjBQN1o0NUZTRjAvRlYzVHZpdVhkSi94MUI0QUk4aCs3TnZqeUh1YkFPU0xo?= =?utf-8?B?bm4vNDBBOTZyRktlTjNZTXEzakx0RFhMOVdxL2FJcjBlYjQya0tMWEpXclRw?= =?utf-8?B?b3Y2ZFBMTUNwbDBnNWZoN2cwdVBXQVAzYldaWVJzVWZRWWc9PQ==?= X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?dkJHYm92UHgzdHdHcVRibXVOcGRkWTVzWGRycVFVMFc0MkdKSEI0bGNYZmFB?= =?utf-8?B?QkljNmpRQ0RBMDhtdU9DZWN6bndJRzc5d3F4ZGJwdjhJVnRKSDM0dHdQVXhU?= =?utf-8?B?T1dGZjJmQUxLMElCNnhSZkVaVm16NDRlczNWSEQ1eGdZTWZYVzhzSTIrcmUy?= =?utf-8?B?bzcrNnZHNFdBa0JuVHd6MjBqMmpZRXVBTHpPdUEvNHdFZGE1MkM5SXlLdlBw?= =?utf-8?B?QnZZZGE5RjM5ZDNRcEN1OU0xeEtrTlcyQmIyWFcrVjRocXNqbmxIZE9Pdy9x?= =?utf-8?B?dHBmOVBldmh1QUtvdnNjeVpwRVdsdVhsUmE4NmVtSHdzZVZLcUw5bnk0M2JP?= =?utf-8?B?T2hRMWZ5cFBxek9QNFVEajltL1crbTRJSGRlemN6R3JHNEZLQXE3QXNvOHBX?= =?utf-8?B?YzhvSm90dTVqUGZrTWc4ZkJQcWMwRnNEVUJIU0tFMitFOWc2RTlLL1Q3RjJx?= =?utf-8?B?SnlZWHdvNVpxRjFPTWRHYzBlWER1Q0RtM0lBOVlDaGt3Si9XMTZ0NFhILzlu?= =?utf-8?B?OStOWDRwSTN1cWcxd3BCRjU0RlFPbjZGRmZtWklpSHgxcUdVVUYzSFNOaWU5?= =?utf-8?B?T3k1OFFKaDhEMFVrcXAycDFyK29Lem9LejJXam00TW9aYVNIMjFwYWIzQ05t?= =?utf-8?B?dThxdnlpTkVuWmlNYXFyZVdzamtCbkVFaVkrT3dYdTJrL0NFa0U0a3g1RkQ0?= =?utf-8?B?TW54dW1wcmR6VkFWQlJ5cWxCaXRHMTZ6WHlzWTF6OGdtTXlPWEg1MlBmbE5x?= =?utf-8?B?ZERnRWJvdWxHbXBkYlVLYXpVajAwMlhPdnBqN2NLMmRZN1NCNE8wenJpR1J2?= =?utf-8?B?LzRiVUg2bHJDeHV1MWZSTGhCalVVaHlsYzRkYW1VQjdhS3hCZ1FHQzdFczN5?= =?utf-8?B?L25UdEs5cHNkWlZ2MHcxaUtYNjBSSDFoSWpsREV3K1JTWmRJTnVvc0M3a3Yy?= =?utf-8?B?Z2hzbG9XTXg2WEw0WXFrOTUwSnhZVysvbGhpdVRMUS9OZjR5MjJyNmtJZFpq?= =?utf-8?B?TjhjOEZjUGs4TUQ4NWgzQlhzS0t1UjkzT3ZVWTNrZE00cy9rN0lXRXFNS0RZ?= =?utf-8?B?SW5PRTVNVHRvd1ZuZ0VsNmRFNHhNVkdrSC9aODdSN01TYzlRYW1Pa045aSta?= =?utf-8?B?UHdBR0hhbGhuZG5VaW5kdFFqcThVTkR3c0J2MERNbGdocFFWZjk3VlVaTng3?= =?utf-8?B?R0lUUDExSkhoeU9YUXVnUWZDZUk1WXQ0YXF3SkJQTGdWcUp0Y1hqSmZybnhK?= =?utf-8?B?N2piRHV4MGxDNzhtOE1MYXNDdzdaQjdtM0J4TGdaUitpQi9tSWg2VjE3SjFh?= =?utf-8?B?ZUN5RW1vUXNYbWxGZDhyVUJTTUhVZnhKd3BuS0tQeUpwdlhJWUMrWjE4MUJJ?= =?utf-8?B?QnByM1lxdGw3VWFJMFhuc2dIcjZiREw0UlVSUnN6SkhIaXY5ck82ZWltaW5x?= =?utf-8?B?NnIxMlNmaDBYWUVnbFY3b3lFdmhrcEJhQzZDVldyS2t5Ym9WWlp2eFVWckw3?= =?utf-8?B?b29HQXpqZDl6djRZRGMrTnhiVjhxblBRZmZiM21GZDU4aURXbFRGRlkvVnVk?= =?utf-8?B?QzN0dzdxOGdieG4vbnNFSlhDa2YveXZIUUVyMGJXSndJZkZvbmZENUZvbUhj?= =?utf-8?B?THo5UExjanJiaVNvNkRBalk3ZVZrcHJSeE91dDJxK1VncEx6UHkvb1dqcnl2?= =?utf-8?B?Z3NSOXMxbXpEUVdaaTNVTWVpUlJkeHQweGptOVE2Vm0wcGE3dURWY3BQUm54?= =?utf-8?Q?dx0PGElf1XXwb9/2uQ=3D?= X-OriginatorOrg: sct-15-20-8534-15-msonline-outlook-5f066.templateTenant X-MS-Exchange-CrossTenant-Network-Message-Id: dce4ea08-f287-4ecd-c9ea-08de1cbc1c8c X-MS-Exchange-CrossTenant-AuthSource: AM8P250MB0170.EURP250.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Nov 2025 22:38:59.6912 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM8P250MB0359 From: bobwei9@hotmail.com (Bob Weinand) Hey Larry, Tim, Seifeddine and Arnauld, On 4.11.2025 21:13:18, 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 months ago; I don't believe either team was aware that the other was also actively 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 particular, 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 questions as listed in the RFC that we are seeking feedback on. > > Discuss. :-) I've been looking at both RFCs and I don't think either RFC is good enough yet. As for this RFC: It makes it very easy to not call the exitContext() method when calling enterContext() manually. The language (obviously) doesn't prevent calling enterContext() - and that's a good thing. But also, it will not enforce that exitContext() gets ever called (and it also cannot, realistically). Thus, we have a big pitfall, wherein APIs may expect enterContext() and exitContext() to be called in conjunction, but users don't - with possibly non-trivial side-effects (locks not cleared, transactions not committed etc.). Thus, to be safe, implementers of the interface will also likely need the destructor to forward calls to exitContext() as well. But it's an easy thing to forget - after all, the *intended* usage of the API just works. Why would I think of that, as an implementer of the interface, before someone complains? Ultimately you definitely will need the capability of calling enterContext() and exitContext() manually too (i.e. restricting that is not realistic either), as lifetimes do not necessarily cleanly nest - as a trivial example, you might want to obtain access to a handle which is behind a lock. You'll have to enter the context of the lock, enter the context of the handle, and close the lock (because more things are locked behind that lock, including the handle). ... But you don't necessarily want the hold on the lock to outlive the inner handle. In short: The proposed approach only allows nesting contexts, but not interleaving them. Further, calling with() twice on an object is quite bad in general. But it might easily happen - you have a function which wants a transaction. e.g. function writeSomeData(DatabaseTransaction $t) { with ($t) { $t->query("..."); } }. A naive caller might think, DatabaseTransaction implements ContextManager ... so let's wrap it: with($db->transaction() as $t) { writeSomeData($t); }. But now you are nesting a transaction, which may have unexpected side effects - and the code probably not prepared to handle it. So, you have to add yet another safeguard into your implementation: check whether enterContext() is only active once. ... Or, maybe a caller assumes that $t = $db->transaction(); with ($t) { $t->query("..."); } with ($t) { $t->query("..."); } is fine - but the implementation is not equipped to handle multiple calls to enterContext(). Additionally, I would expect implementers to want to provide methods, which can be called while the context is active. However, it's not impossible to call these methods without wrapping it into with() or calling the enterContext() method explicitly. One more failure mode, which needs handling. Like for example, calling $t->query() on a transaction without starting it. I don't like that design, which effectively forces you to put safety checks for all but the simplest cases onto the ContextManager implementation. And it forces the user to recognize "this returned object DatabaseTranscation actually implements ContextManager, thus I should put it into with() and not immediately call methods on it". (A problem which the use() proposal from Tim does not have by design.) The choice of adding the exception to the exitContext() is interesting, but also very opinionated: - It means, that the only way to abort, in non-exceptional cases, is to throw yourself an exception. And put a try/catch around the with() {} block. Or manually use enterContext() & exitContext() - with a fake "new Exception" essentially. - Maybe you want to hold a transaction, but just ensure that everything gets executed together (i.e. atomicity), but not care about whether everything actually went through (i.e. not force a rollback on exception). You'll now have to catch the exception, store it to a variable, use break and check for the exception after the with block. Or, yes, manually using enterContext() and exitContext(). It feels like with() is designed to be covering 70% of the use cases, with a load of hidden pitfalls and advanced usage requiring manual enterContext() and exitContext() calls. It's not a very good solution. As to the destructors (and also in reply to that other email from Arnauld talking about PDO::disconnect() etc.): It's already possible today to have live objects which are already destructed. It's extremely common to have in shutdown code. It's sometimes a pain, I agree. But it's an already known pain, and an already handled pain in a lot of code. If your object only knows "create" and "destruct", there's no way for a double enterContext() (nested or consecutive) situation to ever happen. (Well, yes, you *could* theoretically manually call __destruct(), but why would you ever do that?) Last thing - proper API usage forces you to use that construct. To the use() proposal from Tim: This proposal makes it very simple to inadvertently leak the use()'d value. I don't think the current proposed form goes far enough. However we could decide to force-destruct an object (just like we do in shutdown too). It's just one single flag for child methods to check as well - the object is either destructed or not. We could also trivially prohibit nested use() calls by throwing an AlreadyDestructedError when an use()'d and inside destructed object crosses the use() boundary. The only disadvantage is that there's no information about thrown exceptions. I.e. you cannot add a default behaviour of "on exception, please do this", like rolling transactions back. But: - Is it actually a big problem? Where is the specific disadvantage over simply $db->transaction(function($t) { /* do stuff */ }); - where the call of the passed Closure can be trivially wrapped in try/catch. - If yes, can we e.g. add an interface ExceptionDestructed { public bool $destructedDuringException; }? Which will set that property if the property is still undefined - to true if the destructor gets triggered inside ZEND_HANDLE_EXCEPTION. To false otherwise. And, if an user desires to manually force success/failure handling, he may set $object->destructedDuringException = true; himself as a very simple - one-liner - escape hatch. The use() proposal is not a bad one, but I feel like requiring the RC to drop to zero first, misses a bit of potential to save users from mistakes. The other nice thing about use() is that it's optional. You don't have to use it. You use it if you want some scoping, otherwise the scope is simply the function scope. To both proposals: It remains possible by default to call methods on the object, after leaving the with or use block. So some checking on methods for a safe API is probably still required. I don't think it's possible to solve that problem at all with the ContextManager RFC, except manual checking by the implementer in every single method. But it's possibly possible to solve it with the use() RFC in orthogonal ways - like a #[ProhibitDestructed] attribute, which can be added onto a class (making it apply to all methods) or a specific method and causes method calls to throw an exception when the object is destructed. Which is possible to provide by the language, as the language knows about whether objects are already destructed, unlike e.g. the ContextManager, where it would be object state, which has to be maintained by the user. TL;DR: ContextManagers are a buttload of pitfalls. use() is probably better, with much less inherent problems. And with the remaining problems of the proposal being actually solvable. Thanks, Bob