Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:130089 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 553B01A00BC for ; Wed, 18 Feb 2026 15:23:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1771428240; bh=FrKmTe1aCM7PMPtEf47zMsKscrQzKc+L6OIsimMbpcw=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=RrM8n46bxKbhjebo6E64RCzR+QWEgpc4iV9jn3CjHABgyA8MTSSHACK/B33rmvew6 n6Vh1xIc341mHfQSlSu9yBwLWfsrupRDF9gMn9oxKmq89RSte495paCO5LXrXz1UJc LWIdh9xoOWQiZSYTTpaATMdr38KK2f4Sh/oITwl7803wjcF2CdCI6QNBNlUI5E8nRk +G8vK9JjQiJDjEp5HwnHvu7PuGbzMY2xldrs4M8mD77nTS7lwCfBGJjK+y5KDi+8U1 WLcFDjwuxXrITr7urGEbt4YnErwP+uHLZTTVRkdpp1qSadRjkxS0stxuPFIcO8CTRS VPER6I59/AdEw== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 0DAE61801DE for ; Wed, 18 Feb 2026 15:24:00 +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.6 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_50, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS, FREEMAIL_FROM,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-ot1-f54.google.com (mail-ot1-f54.google.com [209.85.210.54]) (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 ; Wed, 18 Feb 2026 15:23:59 +0000 (UTC) Received: by mail-ot1-f54.google.com with SMTP id 46e09a7af769-7d4c1d2123dso5061748a34.2 for ; Wed, 18 Feb 2026 07:23:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1771428234; cv=none; d=google.com; s=arc-20240605; b=K9LI3ox/LbLJYW4B2sLxMHp3YxPnD8/EvsrUG3KNgVQEJaab4ezXW5da71Yr0zQ4lk pLyRR1fSEAD+Zjx7W2vGRv4ugOwzkeVsxhN0qTMyP/jRPE7R8Q8+XYL9HgtLBSJoOd+t jMpnuwXWflakMwRnVx8EpjE9OTUgg2uIeRAh1bcGI87+ZrT5S9s99MbK65Yv5yyoWHQv 8mn8jXnbcO9b8mbsQFh5SzgRioKEDJOqVv0sfFKHGhC8Zp9IXKD170PQ9Sei0PqZAtc2 z69ooeOSbDG6bylYrXcN28K5hCNJG2+Un7eivjpmTQdVe/k385JBiZThpVfFs8ChpYKR uexw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=vB+NfqswSFT2z2a7gphrJrh5PA8QvstrgsGHlqmya7A=; fh=0un1hNQkIQnxRVmSrptHpYePKulyS9pFxhu85Wb7djM=; b=VetP91DWuvbZtyjxP+T6/5ot8pYCinZMR1A5z7ndtao9rmMFdUy77XDLRkc389w6Rk D8QNL6ichkhX/mfmpnq/eLTclqjIUmu10S4V0y41/g3YRJlaQTX22C3xBW7Bumeu9vkl 8GYLOcMI2CMua50TGAwLcDWEhYZoIRlqAM0zu3x9U78lZk3NkUasfw0l1gxFgnpwZox1 vPdPdeiz0biGkORtdAZczL/w0+CAgXySIPCTxG3PI0soGzoZx79I6+obmS6WgMaGdCsb 6BSvjObUGoS8FLG3yh857En3gL9gLyvA276P2oTuYtnDwz59jOn8KkWS8YlYTeu4SDVt n0lg==; darn=lists.php.net ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1771428234; x=1772033034; darn=lists.php.net; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=vB+NfqswSFT2z2a7gphrJrh5PA8QvstrgsGHlqmya7A=; b=Rjh8+QDLUsONEc3Ffl08sh+14riGzdHLovZesw4dCaU0OP4TWt8A/PThX/B32xm6Ay 7LDMCfEFUvzabSpTwVQWISwZxhOrJOXxHcPMhyj3OyCR9NN+tWhFfyOnsFeQ0P+y//Mt H6TX78G/e9TXI20Yl0I10lZljI1zM4XSIckq0vjq+/5eXrFOk1jcJ9/nAHIb4GnfK+nX pyS7Hsx5PwNto4JRpo/W0lVcoYSvreZm7RK2HHEFuql+zzTwDbOr3rrRnsPUZgWzzFld Ieqb8tldWwAPW+/jXwTylm9Vrg904BIAiWpSTkO/ThtkkgtuH3NPKXUnC7K3/jVM1php h8bA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771428234; x=1772033034; h=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=vB+NfqswSFT2z2a7gphrJrh5PA8QvstrgsGHlqmya7A=; b=MXAEzEuEcdHNuIRLwO42LofCY8Eu5hspe+Ckm4k9r+TWHmWIug4Qxg+E87+Hh5dqy6 CB8/sz7eWQ7YqYbvr61LFWc8OXFAzaiAkv7sq3m1A+BPLp+gYYgHo065zMj//Bcp91Ky MX+rLP7D8JGxOBpoLWadkdZGXR0BTGPR3qgyqvdh87uljbUatt9g5US1XNaEeYXrh08W 63boDsWAgG63g0CR0r1gjXAtwtgLqHiLVkgJqmOep+SighoVRFLF3CA/CMt13WkVFY8i GLwPwvpxubCKKgtRbKFuEIA4DHeyONPx8KH5r0qhus1h4AMdaNGOvPWI90tFD0uf8AYI UFhw== X-Gm-Message-State: AOJu0YwutvtN7NtosybH2IIjRBHsbbqLfCVzXJMXgOlyzFzsHtobsFSs +uhTz2GpdN9ChSYFRJK/o39+lkTdGAVXJBmPdWPYvtnlzvftxb5mOYRtxX2vW2LizJ9ZLmerDXL J4HyI7JlTitX6m0CDC/MNm/U3u1MQXZM= X-Gm-Gg: AZuq6aJI6/iALiooyLzZvh2dP7hz1bGVdgVcjYIioBfPENZ88TjkhvR3/N9cX3vBZXN EbezBUXEYqH/ekfrgC9RyEEPGHpN3oaY3PGuqWIWcZqLgolO5WdwYY6+SOc8DN8ev8k3TMLu28w NaLaF97EhP0q9nBb4iEYwfVa6Q/ThG3D/Q6x9LQjj2azN8bDokbgVxawyq2nVkGe9bSz4N6QesJ JeC57v0IxIHi/AlfibrcLGRDEot9i0DyE/B0eruLkMVTbDKZiErzOZf96MWYoTSPxHc5fMYGzk5 tSzmYHHEhK2POilw8QPZTzSId+qhMtwafHw5 X-Received: by 2002:a05:6830:618d:b0:7d1:9516:6858 with SMTP id 46e09a7af769-7d505e16c0bmr1811582a34.24.1771428234064; Wed, 18 Feb 2026 07:23:54 -0800 (PST) Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 References: <1f25d77e-224b-40d6-bf19-18dfdfc9de54@rwec.co.uk> <453bc043-b4ee-423e-9561-55510f5c20a7@rwec.co.uk> In-Reply-To: <453bc043-b4ee-423e-9561-55510f5c20a7@rwec.co.uk> Date: Wed, 18 Feb 2026 16:23:43 +0100 X-Gm-Features: AaiRm51lJIrFKW0H02ko0Fu8hTH06ebb60dsxg6wtjytkdChVKsGspKytw6MElg Message-ID: Subject: Re: [PHP-DEV] [IDEA for RFC] let the "new" operator fail when the __construct() function returns a value. To: "Rowan Tommins [IMSoP]" Cc: internals@lists.php.net Content-Type: text/plain; charset="UTF-8" From: mirco.babin@gmail.com (Mirco Babin) Op di 17 feb 2026 om 20:26 schreef Rowan Tommins [IMSoP] : > > On 17/02/2026 06:59, Mirco Babin wrote: > > I disagree with the compiling part. The __construct() function can > > currently not have a return type, so the return type is implicitly > > "mixed". Changing that would be a BC break for those calling the > > __construct() function as a regular function. > > > It's a BC break either way - which is fine, if it only happens in PHP 9.0. > > > Consider this example in your draft RFC: > > ``` > class UnaffectedBaseClass > { > public function __construct() > { > return ['important']; > } > } > ``` > > Right now, there is nothing stopping someone calling that constructor as > `new UnaffectedBaseClass`. In PHP 9.0, that working code will become an > error - a BC break. > > This is true even if the class is marked `abstract`: > > ``` > abstract class AbstractBaseClass > { > public function __construct() > { > return ['important']; > } > } > > class ValidSubClass extends AbstractBaseClass > { > } > > $it = new ValidSubClass(); // Error in PHP 9.0 > ``` I have added this example to the RFC. > In fact, the only way to guarantee a class is unaffected would be to > write a method called "__construct", but then use static analysis to > prove that nothing actually uses that method as a constructor. At the moment, without changing anything to Php, PHP Code Sniffer static analysis is the only option. Would this RFC be accepted, there are at least additional deprecation notices. But to be sure upfront, you still would have to use PHP Code Sniffer. > In which > case, why use the reserved name "__construct"? I'd go one step further. Why can "__construct" be called as a regular function? Why not prohibit that and make it a truly magical function? FYI: I have added "Ban __construct() as a regular function call" to the rejected features section. Banning the __construct() as regular function call, except when called as "parent::__construct()", is a rejected feature for this RFC. * Only the "new" keyword and "parent::__construct()" would then be allowed to call the %%__construct()%% constructor. * The __construct() would only serve as constructor. It would become truly a magic function. * Lazy ghost and ReflectionClass::newInstanceWithoutConstructor() would be a challenge. * This would go hand in hand with a implicit change to "void" return type declaration. * The goal of this RFC is minimal BC impact. This would have major impact. > My suggestion is that classes which are affected should show an error > *as soon as possible*, so that users are prompted to fix the definition. > > In the example above, I would much prefer to see the error (or > deprecation notice) as soon as AbstractBaseClass is compiled, rather > than waiting for something in the code base to call "new ValidSubClass". That's a personal preference. Sometimes I want compilation errors right away, but often I just want it to work. And if one web page crashes because of an incorrect "return," I'd rather fix it on the fly than get stuck with all sorts of compilation errors that I'm forced to resolve. Because the other webpages then do work, it is just 1 that is broken. It's about the obligation to fix it upfront versus fixing it when it goes wrong. Fixing it upfront is a black/white scenario, either it works or it fails. Fixing it when it goes wrong is a gray scenario, it works until it breaks. > Similarly, if there's a long constructor with a return statement inside > some rarely used conditional logic, I would prefer to be told > immediately that there is a mistake, rather than having a production > error when the rare situation happens. Normally, there's a test phase in between. There's always a chance that the test phase will already detect the faulty web page. > Once I'm told about the problem, I can choose between two things: > > 1) Stop the constructor returning a value, e.g. by replacing "return > foo();" with "foo(); return;" > 2) Rename the method to a non-reserved name, and if needed add a new > constructor which calls the method and discards the result There is a 3rd option: if ($calledAsRegularFunction_and_not_as_constructor) { return foo(); } > Thinking that through, having an error thrown only when calling with > `new` would actually be *more* disruptive. I would probably vote "No" to > that version of the proposal. FYI: I have added "Changing to void return type declaration" to the rejected features section. There already was "aborting during compilation" in the rejected feature section. Conclusion: =========== There are two conflicting goals in the prologue: "Maximum warning" and "Minimal BC impact". You prioritize Maximum warning. I prioritize Minimal BC impact. Your points are correct, from the perspective of a new PHP project. However, reasoning from the perspective of a very old PHP project, every BC break is one too many. It works now, so why should something be changed? This old project has no security issues whatsoever. E.g. because it is an internal project, a cli tool, something that is not public. FYI: I updated the prologue. "This RFC prioritizes minimal BC impact above all else." Kind regards, Mirco Babin