Take the State of PHP 2026 Survey →

Make constructors and destructors return void View as Markdown

Declined
Authors
Benas Seliuginas, benas.molis@gmail.com
Date
2020-06-17
Target
PHP 8.0
Source
wiki.php.net/rfc/make_ctor_ret_void

Votes

Make constructors/destructors return void? closed
Yes
34
No
22
56 voters
alcaeus Yes 2020-07-10 08:58
alec Yes 2020-07-09 06:03
asgrim Yes 2020-07-11 18:24
ashnazg Yes 2020-07-15 18:40
beberlei No 2020-07-09 10:40
bmajdak Yes 2020-07-09 00:09
brandon No 2020-07-15 13:41
brzuchal No 2020-07-09 14:08
bwoebi No 2020-07-08 21:10
carusogabriel No 2020-07-09 08:15
cpriest Yes 2020-07-13 21:42
dams Yes 2020-07-17 17:35
daverandom Yes 2020-07-14 21:06
derick No 2020-07-08 20:59
dragoonis No 2020-07-09 07:51
ekin Yes 2020-07-09 14:54
galvao Yes 2020-07-12 13:02
girgias Yes 2020-07-08 21:18
guilhermeblanco Yes 2020-07-22 15:09
heiglandreas No 2020-07-09 07:04
ilutov Yes 2020-07-08 20:57
irker Yes 2020-07-10 12:27
jasny Yes 2020-07-17 13:06
jbnahan Yes 2020-07-09 07:15
kelunik Yes 2020-07-09 14:14
kguest No 2020-07-17 15:50
kocsismate Yes 2020-07-08 20:44
kriscraig No 2020-07-10 02:52
levim Yes 2020-07-15 14:13
marcio Yes 2020-07-15 05:33
mariano Yes 2020-07-09 13:19
narf Yes 2020-07-09 16:33
nicolasgrekas No 2020-07-09 07:54
nikic Yes 2020-07-08 21:04
nohn No 2020-07-09 07:26
ocramius Yes 2020-07-09 00:36
patrickallaert No 2020-07-10 08:20
pollita No 2020-07-17 14:40
rasmus No 2020-07-08 23:02
reywob No 2020-07-09 15:35
rmf Yes 2020-07-15 10:54
salathe No 2020-07-09 09:14
sergey Yes 2020-07-10 09:19
sirsnyder No 2020-07-09 22:06
stas No 2020-07-08 20:33
subjective Yes 2020-07-09 19:50
svpernova09 No 2020-07-10 17:01
tandre Yes 2020-07-16 13:31
theodorejb Yes 2020-07-08 20:53
thorstenr Yes 2020-07-10 12:15
trowski Yes 2020-07-10 15:56
twosee Yes 2020-07-14 04:51
weierophinney Yes 2020-07-11 15:51
wyrihaximus Yes 2020-07-21 12:11
zeev No 2020-07-09 16:06
zimt No 2020-07-22 07:30
Allow void return type on constructors/destructors? closed
Yes
27
No
25
52 voters
alcaeus Yes 2020-07-10 08:58
alec Yes 2020-07-09 06:03
asgrim Yes 2020-07-11 18:24
ashnazg Yes 2020-07-15 18:41
beberlei No 2020-07-09 10:40
bmajdak Yes 2020-07-09 00:09
brzuchal No 2020-07-09 14:09
bwoebi Yes 2020-07-09 13:46
carusogabriel No 2020-07-09 08:15
cpriest Yes 2020-07-13 21:42
daverandom Yes 2020-07-14 21:06
derick No 2020-07-08 21:00
dm No 2020-07-10 13:35
dragoonis No 2020-07-09 07:51
ekin No 2020-07-09 14:54
galvao Yes 2020-07-12 13:02
girgias Yes 2020-07-08 21:18
guilhermeblanco Yes 2020-07-22 15:10
heiglandreas No 2020-07-09 07:07
irker Yes 2020-07-10 12:27
jasny No 2020-07-11 12:14
jbnahan Yes 2020-07-09 07:16
kelunik Yes 2020-07-09 14:14
kguest No 2020-07-17 15:51
kocsismate Yes 2020-07-08 20:44
kriscraig No 2020-07-10 02:53
levim No 2020-07-15 14:13
marcio Yes 2020-07-15 05:32
mariano Yes 2020-07-09 13:20
narf Yes 2020-07-09 16:33
nicolasgrekas No 2020-07-09 07:54
nikic No 2020-07-09 13:29
ocramius Yes 2020-07-09 00:36
patrickallaert No 2020-07-10 08:19
pollita Yes 2020-07-17 14:40
rasmus No 2020-07-08 23:03
reywob Yes 2020-07-09 07:26
rmf Yes 2020-07-15 10:55
salathe No 2020-07-09 09:15
sergey No 2020-07-14 08:55
sirsnyder Yes 2020-07-09 22:06
stas No 2020-07-08 20:33
subjective Yes 2020-07-09 19:51
svpernova09 No 2020-07-10 17:01
tandre No 2020-07-16 13:31
theodorejb No 2020-07-08 20:53
thorstenr Yes 2020-07-10 12:16
trowski No 2020-07-10 15:57
twosee No 2020-07-14 04:51
weierophinney Yes 2020-07-11 15:51
wyrihaximus Yes 2020-07-21 12:11
zimt No 2020-07-22 07:31

Discussions on the mailing list

[RFC] [DISCUSSION] Make constructors and destructors return void
by Benas IML · 17 messages
[RFC] [VOTE] Make constructors and destructors return void
by Benas IML · 22 messages

RFC text

Copied from wiki.php.net, last synchronized Oct 13, 2026 11:52 UTC

Large credit for this RFC goes to Michael Voříšek who initially reported the bug and created a draft-- patch.

Introduction

At the moment, constructors and destructors can return values. However, these magic methods are supposed to be void (according to the documentation) and should not return a value. This RFC proposes to deprecate this behavior in PHP 8.0 and subsequently in PHP 9.0 enforce void rules on constructors and destructors.

This would apply both implicitly, where no return type is declared for the constructor/destructor, and explicitly where a void return type is declared.

Proposal

Status quo

Currently, void rules are not enforced for constructors and destructors. Thus, it is allowed to return values from those magic methods:

<?php
class Test {
	public function __construct() {
		return 0;
	}
 
	public function __destruct() {
		return 1;
	}
}
 
$test = new Test();
 
// this prints 0
echo $test->__construct();
// this prints 1
echo $test->__destruct();

But the PHP manual states, that constructors have void return type (i. e. don't return a value). Therefore, the current behavior is inconsistent and incorrect. The void return type rule should always be enforced on constructors/destructors, no matter if the void return type declaration is implicit or explicit.

Proposal

This RFC proposes:

  • to deprecate the ability of returning values from constructors and destructors in PHP 8.0.
  • to treat both constructors and destructors that do not have an explicit return type, as if they have a return type of void in PHP 9.0.
  • to allow explicit void return type on constructors and destructors (secondary vote).

A deprecation warning would be generated:

  • for any constructor or destructor that returns a value in PHP 8.0

Note: if there is an explicit void return type, a fatal error will be generated instead. This allows for newer codebases to take advantage of the check in PHP 8.0 already.

A fatal error would be generated:

  • for any constructor or destructor that returns a value in PHP 9.0.
  • for any constructor or destructor that has an explicit return type other than void (secondary vote).
<?php
class Test {
	public function __construct() {
		// this is illegal
		return 0;
	}
 
	// this is also illegal
	public function __destruct(): mixed {}
}
 
class Test2 {
	// this is legal (secondary vote)
	public function __construct(): void {}
 
	// this is also legal
	public function __destruct() {}
}

Backwards incompatible changes

Accepting this RFC results in a small backwards compatibility break in PHP 9.0 since it will no longer be legal to return (mixed and any of its subtypes) values from constructors and destructors.

The position of this RFC is that this BC break is minimal, as returning values from constructors/destructors is not a standard pattern used by many pieces of code. However, to minimize the number of BC breaks even further, the ability of returning values from constructors/destructors is deprecated in PHP 8.0.

Unaffected functionality

Explicit return type declaration is optional

Explicitly declaring the return type declaration would be optional. It would still be allowed to not specify a type at all:

<?php
class Test {
	// this is legal
	public function __construct() {}
 
	// this is also legal
	public function __destruct(): void {}
}

Constructors are exempt from inheritance checks

Since constructors are exempt from inheritance checks, it is allowed to widen the type from a child class. For example, if the parent class has explicitly declared the constructor as void, it would still be allowed to widen the type to no return type. In other words, covariance (for return types) does not apply to constructors.

<?php
class Test {
	// this is legal
	public function __construct(): void {}
}
 
class Test2 extends Test {
	// this is also legal
	public function __construct() {}
}

Why allow void return type on constructors/destructors?

Enforcing void rules on constructors/destructors implictly but not allowing to declare an explicit type is going to create inconsistencies.

It's key to understand that constructors and destructors in PHP don't work the same way that they do in other languages. First of all, unlike in other languages, constructors and destructors are rather normal functions in PHP and can be called directly i. e. through $object->__construct() and $object->__destruct(). Adding an explicit void return type acts as an extra marker that takes the reader from 99% certain to 100% that these functions are not supposed to return anything. This also aligns with the PHP manual which states that constructors/destructors have a return type of void and the Zen of Python's 2nd principle (“Explicit is better than implicit”). Thus, saying that other languages don't have a concept of return types for constructors does not make much sense in PHP's case.

Rowan Tommins comment on the internals mailing list should also be taken into consideration: “The way I look at it, constructors are mostly declared like a normal method - they use the keyword “function”; can be marked public, private, protected, abstract, and final; and can have a parameter list, with types and defaults - so the surprising thing is that there is a special rule *forbidding* them from having a return specifier”.

Another argument that is used against allowing explicit void return type is that it's going to create code-style wars and is duplicate information. But arguably, everyone also already knows what functions such as __toString() return. You know it's going to be a string. That's its whole purpose. It would be surprising to see any code style forbidding that. Moreover, as of PHP 8.0, constructors and destructors will be the only methods that are not allowed to have a return type. This will be quite inconsistent given that __clone magic method will be able to have an explicit void return type even though both object construction and object cloning work in a similar fashion.

Vote

Primary

Vote: Make constructors/destructors return void? — Yes: 34 · No: 22 (closed)

Secondary

Vote: Allow void return type on constructors/destructors? — Yes: 27 · No: 25 (closed)

Implementation

GitHub Pull Request