Re: [IDEA for RFC] let the "new" operator fail when the __construct() function returns a value.

From: Date: Thu, 05 Feb 2026 17:40:46 +0000
Subject: Re: [IDEA for RFC] let the "new" operator fail when the __construct() function returns a value.
References: 1 2  Groups: php.internals 
Request: Send a blank email to internals+get-130021@lists.php.net to get a copy of this message
>Can you elaborate on this? I'd like to better understand what the >problem was with constructors that returned values when you upgraded >from Laravel 9 to Laravel 12. I can't share real code, because this project is not open source. The project I maintain uses constructor middleware as follows: ```php // Laravel 9 class MyController extends Controller { public function __construct() { $this->middleware(function ($request, $next) { if (!Security::isLoggedIn()) { return redirect()->route('login'); } return $next($request); }); } } ``` The goal is to redirect guests to the login page. To prevent unauthorized actions from being performed. In Laravel 9, MyController was instantiated before any middleware was executed. When __construct was executed, Laravel was still initializing, not much could be done in the __construct function. Hence the middleware solution. Then came Laravel 12 and constructor middleware was removed. Also, middleware is now executed before the controller is instantiated. And here's where I made my mistake. I removed the $this->middleware() call, and changed this to: ```php // Laravel 12 - my mistake, this it totally wrong! class MyController { public function __construct() { if (!Security::isLoggedIn()) { return redirect()->route('login'); } // Because the return value is pointless, no redirection // did find place. // The unauthorized user could actually call real controller // functions, which could be anything from showHomepage() to // rebootTheSystem() - exaggerated of course. // // But PHP did not warn me, did not error, did not speak up, // did nothing to inform me of my mistake. } public function showHomepage(Request $request) { } public function rebootTheSystem(Request $request) { } } ``` >So, to restate your proposal: you want to disallow returning from >constructors…but only if invoked when using the new keyword? That is correct. >So, if you call $object->__construct(), there's no >error, and you can >get the return value, but if you do new Foo(), you'd get an >error? That is correct. >The "Make constructors and destructors return void" RFC was voted on and >declined in 2020. PHP has come a long way since then, and I'm curious >whether a similar proposal (targeting PHP 9) might pass nowadays. I'd >certainly consider voting for it. Perhaps in PHP 8.6, we could begin >emitting a deprecation message for constructors that return values? Deprecation sounds like a good step forward. Kind regards, Mirco Babin

« previous php.internals (#130021) next »