[PHP-DEV] [RFC] Deprecate returning values from __construct() and __destruct()

Hi

following Rowan’s request from the earlier “let the "new" operator fail when the __construct( ) function returns a value” discussion [1], I have now created a dedicated RFC to deprecate returning values from __construct() and __destruct().

Please find the RFC text at: PHP: rfc:deprecate-return-value-from-construct

Best regards
Tim Düsterhus

[1] php.internals: Re: [IDEA for RF C] let the "new" operator fail when the __construct( ) function returns a value.

On 08/05/2026 09:44, Tim Düsterhus wrote:

Hi

following Rowan’s request from the earlier “let the "new" operator fail when the __construct( ) function returns a value” discussion [1], I have now created a dedicated RFC to deprecate returning values from __construct() and __destruct().

Please find the RFC text at: PHP: rfc:deprecate-return-value-from-construct

Hi Tim,

Thanks for writing this up.

In terms of the proposal, I am thoroughly in favour. Deliberate use of a return value here is rare, and refactoring to use a non-magic helper method should generally be fairly easy.
It's also in line with restrictions added to other magic methods - e.g. calling __toString() directly could return any value until 8.0, but it now acts as though declared with a return type of "string".

In terms of the RFC text, though, I think there should be more than a "see also" link to the previous RFC at PHP: rfc:make_ctor_ret_void This went to a vote and was declined (with a majority in favour, but not the required super-majority), so I think the new RFC should explain how either a) the new proposal is different from the old one; or b) the circumstances are different from when they were last voted.

(I think our policy wording on this [1] probably needs to be tightened up slightly; as written, it implies that a failed proposal could be brought to vote unchanged every 6 months, until the author got the result they wanted.)

[1] policies/feature-proposals.rst at main · php/policies · GitHub

Regards,

--
Rowan Tommins
[IMSoP]

On Sat, May 9, 2026, at 9:09 AM, Rowan Tommins [IMSoP] wrote:

On 08/05/2026 09:44, Tim Düsterhus wrote:

Hi

following Rowan’s request from the earlier “let the "new" operator
fail when the __construct( ) function returns a value” discussion [1],
I have now created a dedicated RFC to deprecate returning values from
__construct() and __destruct().

Please find the RFC text at:
PHP: rfc:deprecate-return-value-from-construct

Hi Tim,

Thanks for writing this up.

In terms of the proposal, I am thoroughly in favour. Deliberate use of a
return value here is rare, and refactoring to use a non-magic helper
method should generally be fairly easy.
It's also in line with restrictions added to other magic methods - e.g.
calling __toString() directly could return any value until 8.0, but it
now acts as though declared with a return type of "string".

In terms of the RFC text, though, I think there should be more than a
"see also" link to the previous RFC at
PHP: rfc:make_ctor_ret_void This went to a vote and was
declined (with a majority in favour, but not the required
super-majority), so I think the new RFC should explain how either a) the
new proposal is different from the old one; or b) the circumstances are
different from when they were last voted.

(I think our policy wording on this [1] probably needs to be tightened
up slightly; as written, it implies that a failed proposal could be
brought to vote unchanged every 6 months, until the author got the
result they wanted.)

[1]
policies/feature-proposals.rst at main · php/policies · GitHub

Regards,

--
Rowan Tommins
[IMSoP]

I agree with Rowan on both fronts. +1 on the feature, but also +1 on better explanation of why this attempt is better/different/more worthy of support than previous attempts.

--Larry Garfield

Hello Tim Düsterhus,

following Rowan’s request from the earlier “let the "new" operator fail
when the __construct( ) function returns a value” discussion [1], I have
now created a dedicated RFC to deprecate returning values from
__construct() and __destruct().

Please find the RFC text at:
PHP: rfc:deprecate-return-value-from-construct

The RFC should also include "yield". Because "yield" also returns a value.

For example:


class SomeTheoreticalYieldExample
{
    public $value;

    public function __construct()
    {
        $this->value = 'Some value';
        yield 1; // Deprecated: yielding from a constructor is deprecated
    }
}

$it = new SomeTheoreticalYieldExample();
var_dump($it->value); // PHP 8.5 surprise/bug, it is NULL

Kind Regards,
Mirco Babin

As I mentioned in my earlier message about this topic [1], a PHP_CodeSniffer sniff already exists to forbid this. For lack of an impact analysis in the RFC, I’ve now used this sniff to create an impact analysis [2] based on the Packagist 4000 as downloaded by me some two months ago. Configuration used and full scan results are available in the gist. Smile, Juliette [1] [2]

···

On 8-5-2026 10:44, Tim Düsterhus wrote:

following Rowan’s request from the earlier “let the “new” operator fail when the __construct( ) function returns a value” discussion [1], I have now created a dedicated RFC to deprecate returning values from __construct() and __destruct().

Please find the RFC text at: https://wiki.php.net/rfc/deprecate-return-value-from-construct

https://externals.io/message/129980#130043
https://gist.github.com/jrfnl/6782310676b7ff5942f97873a71552ea

Hi

Am 2026-05-21 10:01, schrieb Mirco Babin:

The RFC should also include "yield". Because "yield" also returns a value.

For example:
Online PHP editor | output for Z4dMTF

Good catch, thank you.

I have adjusted the RFC to mention that making the constructor and destructor a Generator is effectively equivalent to returning a value and thus will also be deprecated.

Best regards
Tim Düsterhus

Hi

Am 2026-05-28 19:19, schrieb Juliette Reinders Folmer:

For lack of an impact analysis in the RFC, I've now used this sniff to create an impact analysis [2] based on the Packagist 4000 as downloaded by me some two months ago.
Configuration used and full scan results are available in the gist.

Thank you. I included the information in the RFC Impact section.

Best regards
Tim Düsterhus

Hi

Am 2026-05-09 16:09, schrieb Rowan Tommins [IMSoP]:

In terms of the RFC text, though, I think there should be more than a "see also" link to the previous RFC at PHP: rfc:make_ctor_ret_void This went to a vote and was declined (with a majority in favour, but not the required super-majority), so I think the new RFC should explain how either a) the new proposal is different from the old one; or b) the circumstances are different from when they were last voted.

I'm really struggling to find something meaningful to write down, because to me this very much feels like an obvious fix. I think (b) most closely fits here with the overall theme of the direction PHP is going being “point out mistakes rather than silently continuing doing something the user likely didn't intend”. I feel this is similar to PHP: rfc:policy-exempt-type-value-error-bc-policy where we already decided that pointing out invalid inputs is preferable to “just do something”.

(I think our policy wording on this [1] probably needs to be tightened up slightly; as written, it implies that a failed proposal could be brought to vote unchanged every 6 months, until the author got the result they wanted.)

Increasing the time between substantially identical proposals makes sense to me, 6 months could mean that the same proposal comes up twice for the same PHP version. But I think that after several years it's reasonable to just agree that “PHP today is different from the PHP back then” and have another vote on an otherwise unchanged proposal.

Best regards
Tim Düsterhus