Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:130097 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 8EAF51A00BC for ; Thu, 19 Feb 2026 20:25:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1771532716; bh=I6xGjgYJRYL23A37m8lxtpUaWP9Hc4hVputIbeylyko=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=oBnR14oOlgP49Ippi36j3tCMZFJclIY9gwympUvCZmcAZBngo0izsXTeGH0nkX/nz GPobtAHkx0/nndrgVdI8q4lfITavpZJoa5FRfd4qcZtR1fa9zgjqms14KmYl0xw7AP brkofrehIOfAWXYC2C0Zxi6RdQgmXmY10uFV3crCytiIN1L/sO1kkyFJXEWDDE2KA5 he2CSBFCt/jRxe98E4n8IPZcPLz8xufz3DxOsI6bNGv4ATvZDqiAeVCP9AA1dsSlFm huwdEq4pKlwCijZcB4ujqi757Bc2vx9B/r+xwvul9Ip8piMJYcIO+RX7eoQehMaP1p qmuRa8AIJdmEQ== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id D80AD180048 for ; Thu, 19 Feb 2026 20:25:14 +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-f49.google.com (mail-ot1-f49.google.com [209.85.210.49]) (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, 19 Feb 2026 20:25:14 +0000 (UTC) Received: by mail-ot1-f49.google.com with SMTP id 46e09a7af769-7d4bc6a8021so1057173a34.3 for ; Thu, 19 Feb 2026 12:25:09 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1771532709; cv=none; d=google.com; s=arc-20240605; b=HJyiQNN81eYROJ0Co5ZlD83R6ctAQE+FHzZzAaWwfedBFaloKeKFf3zDy6f1wJaE6+ 9X5ZQkjR17RkCBVqSGd47cvWXLcXW6jhQydVTjDT9P3G7+o4/uK/UJu+Z7WTiBzqGHSX Fb41tMikcee/11l3n8xVpoK5J66v+5w2MT4dJNVsslPcapopbOgY+ysIyOvZRkC8KmXX JXQ+Hgp9H8Kh71uweFvI5NaA6TSdwMe7Ji0JNnA4zRobszTfoP+dJYfOSk8n7XgGKngU mM4UGj5XwwlNx7EhRGca3vMIyuT7MkGoACCLwOJ3CeD7z8WXh7a+QhyRbsGCpewxOrA9 ZYjQ== 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=Ji4PtVNxkenLdcZBZ/AKy+blGt/ftfQQV3+bwVCoK9A=; fh=0un1hNQkIQnxRVmSrptHpYePKulyS9pFxhu85Wb7djM=; b=eHJ+vJLoDJZkm48CxHwxUsWfVnAXYCeSwfEuGdEDb7cIQ4UtVO0D3NOGV1WiFpgo6W NHmLdh1sQ2wmANCCQHqIJdvOB2aZ3fck3Ev7gET3wm7Znx7O8iRijyuj9StaOqlD1kYW yGW8cLDb7pXClvz01iq+VjKuaIPyYYGQIRnFEXniQtuDl3p+Qq6a0GMKUWA2lL2nZfCH 6TxK3s4MTUdBDvEPThPy2WgQocHdRxp4WuZFrrz16i8kLdHrpARBsqtmUddxNvnvPPBF 4Pw+DIHBmdlbjwJ0xut35Pb9sDMb8zDB3d9ifALalrUlWbRbFE5mi0AmnXcdlI6DIV2p 2WMA==; 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=1771532709; x=1772137509; 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=Ji4PtVNxkenLdcZBZ/AKy+blGt/ftfQQV3+bwVCoK9A=; b=ZK+Td91bO9bCJf05mgOR6XLwDvUt/3nASr4apv1aR55EhIiO9z74qMNZwMuVXCS2Ym UzlXfVAcAxRua9Xx1xh4DgpNgtbBFtoZ91EfxzCqJYsEDf1QF8k1ju6AvwNkao7BVKuU 2Fc3zAcMSld6ZwTzRzdfVlLYSsIPotNSk6tCk/67BKXCn8Qyua6ABgYQi+KTmxxasQ0S q2SLkaFlVh+5PQSuGg9P6g8qHDquHFoKNSdSZ6bn0+8ztdpIhZev+LRTt9seg8YzpITG RvHWv/SNJSkl+I/4VTyxHaO0NgEYkSp9uIHunAynM/68DLuAwfRCRkKYSbve9YMTwd94 uDAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771532709; x=1772137509; 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=Ji4PtVNxkenLdcZBZ/AKy+blGt/ftfQQV3+bwVCoK9A=; b=c6PSaVjWZX5eYNU2YLGpEzWmN+a5pbq+dUsdIJS61omf0EQOTxY1DYGGc52IL2oVnL /w2Pl9GYa5MgLNDr7qG1LHl7DUeRwHt2/zvi2j8trpEMXpYy70VDQskUl5a71PSqU5Nn JZoppCQfnzRFbVB9X+KJ/xLgjm8/2L6OjsOtTHraq+aeCtCVCPS1a+dye9pirjRB5TON pC/YkfFhzc1jr9s1j+uofhjxobPeg1wAzGspFCtQBYWd4d9nn+EpGN+FzoO07remTvm4 6ouY4JhnE9bY5Qgl3RNFV7Hnwv4q5kl4pW+erB0TIYUr3euVmAEVjZu9xTeSqC/DtBB9 md1g== X-Gm-Message-State: AOJu0Ywrebqv0PIoM6u8PtclRv1F+44psT1iCoP8xjlZWoiGKigerU52 Gmxcj2WfAy3gD9UYYG2kAO6cnE8N1RON8N5+bOtEu42lqd6p5tt5CDxi5+IHUhtBO3rrfS0G8xu wZkTsuzs00mRdjl+pvoegQg5KZeNgLWI= X-Gm-Gg: AZuq6aJGwpJHV8CnaNNn72wCBUaDd+ezqV7gYFHcq8WoNIIOXebC6/PSYZOLgFNRQNs g8HhKGPGjOKx0mbCcLiFKq3z7skzybAyqV70eLoGkd+ZgIXWq8bjCtcKnUYUAyP5tqlBVahe5/Z wUaQmzujznf4r46/jmpq3zi9+hKD1fHZZ0iXWU6D5Ek5FsFWK8CD7D5aFutj+bMDsrlr9tPRrQy d1/KytuG6KDpDopTsfQcmAvPtPtkmR/JGAYFbfestPLlsKEY9ETCTCoPEW1FdRz2f0a3U2+1FGp p2aI1+9vbL52hAJ34KyVTl9xLKwE+hNDBfYp X-Received: by 2002:a05:6830:3808:b0:7c7:80e5:245f with SMTP id 46e09a7af769-7d4d0c3a067mr10225595a34.30.1771532708783; Thu, 19 Feb 2026 12:25:08 -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: Date: Thu, 19 Feb 2026 21:24:56 +0100 X-Gm-Features: AaiRm50ICcUqazCw1Po1giMnx5zbJpcMOI9kprlHYrwRuPzwIu-noz5kePdxRnw 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 do 19 feb 2026 om 13:54 schreef Rowan Tommins [IMSoP] : > On 18/02/2026 15:23, Mirco Babin wrote: >>> >>> 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. > > > The deprecation notices will tell you about code that *is* affected, > but they can't prove that code is *not* affected, if they only happen > at run-time. That is correct. I'm aware of that. Prove can be obtained by using 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? > > > That's a different kind of "why". I meant, "why would a programmer > deliberately call a function __construct, and have no intention of > *ever* using it as a constructor". A theoretical example can be found in "Unaffected calling the parent constructor example". UnaffectedBaseClass could be abstract. ```php class UnaffectedBaseClass { public function __construct() { return ['important']; } } class UnaffectedCallParentConstructor extends UnaffectedBaseClass { public function __construct() { $important = parent::__construct(); } } $it = new UnaffectedCallParentConstructor(); ``` > If they are using it as *both* a constructor and a normal method, > *their code will break with your proposal* because at some point > they will call it as a constructor and hit the new error. Not necessarily. When an if is used, __construct() can be either. ```php class UnaffectedConstructorAndRegularFunction { public function __construct($input = null) { if ($input === null) return; return ['important', $input]; } } $it = new UnaffectedConstructorAndRegularFunction(); $important = $it->__construct('more important'); ``` >>> 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. >> >> That's a personal preference. >> > > Yes and no. Detecting problems early is widely recognised as reducing > the cost and risks of a project. See for instance discussion around > the term "shift left". The RFC prioritizes minimal BC impact. That won't change. If someone really wants early detection, that someone should be programming in C# and not in PHP. The Php scripting aspect makes it difficult in general for untyped projects to fail early. The same applies to spaghetti projects. >>> 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(); >> } > > > Can you point to any real-life example of this? No, it is theoretical. > > It feels like a lot of this discussion of BC breaks is assuming > that there's some common code pattern relying on the current > behaviour, but the only examples I've seen so far are of why > it would be *wrong* to return a value. I have given 2 theoretical examples: - UnaffectedConstructorAndRegularFunction - UnaffectedCallParentConstructor Has anyone ever used it? Probably, considering PHP's age and how long it's been possible to abuse the __construct() function. >> There are two conflicting goals in the prologue: "Maximum warning" >> and "Minimal BC impact". You prioritize Maximum warning. I prioritize >> Minimal BC impact. > > I disagree that your proposal has a lower BC impact. > > The majority of code that currently relies on a constructor returning > a value *will break under both versions of the proposal*. Not true, see the 2 supplied examples. The "void" variant would break, my variant would run unaffected. > The only difference that delaying the error to run-time makes, is that > it will take longer for people to notice that it is broken. Not necessarily true. Assume the code is running fine on a shared hosting platform with Php 8.5. Then the hosting provider decides to force an update to Php 9, because of a critical vulnerability. That same code would then break at some point. Depending on the structure of the project, the amount of routes handled in one Controller class, and where the mistake is programmed, the whole website will break, or only parts of it. The "void" variant breaks immediately when the source is compiled. My variant only breaks when the pattern is detected and leaves other parts untouched. In this production example, a break that always occurs is actually annoying. The more parts can continue working uninterrupted, the more time a developer has to fix the problem. >> 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 is exactly those old PHP projects that I'm worried about. The ones > that have poor testing coverage, large amounts of spaghetti code, and > will cause some poor engineer to have a 2am alarm because someone the > other side of the world just crashed the application with a run-time > error. I assume the mistake I made doesn't happen often. If it did, I wouldn't be working on this RFC now, but a mechanism would already be active in PHP. I assume the spaghetti contains some version of my two theoretical examples. So it is safer to *not* make the return type declaration implicitly "void". Kind regards, Mirco Babin