On 2/2/26 12:00, Mirco Babin wrote:
# Problem

The "new" operator internally calls the __construct() function. However,
the return value of the __construct() function is silently lost. This is
very error-prone; I personally made a major security mistake with this when
upgrading from Laravel 9 to Laravel 12.

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.

To prevent future problems, my proposal is to have the "new" operator
explicitly issue warnings, and later have it explicitly abort when the
__construct() function returns a value.

So, to restate your proposal: you want to disallow returning from constructors…but only if invoked when using the `new` keyword?

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?

And I've been told that the
rejected PHP RFC Make constructors and destructors return void
( https://wiki.php.net/rfc/make_ctor_ret_void ) rejects my proposal.
However, my proposal is explicitly about the "new" operator and not
about return types. It does, however, concern return values.
I'm not sure how this differs from the void return type proposal. When it throws a TypeError, it will effectively be saying, "this method can't return anything," which means the return type is `void`.

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?

Cheers,
Ben

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature

Reply via email to