php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #76311 __construct/__destruct must not have return types
Submitted: 2018-05-08 15:37 UTC Modified: 2021-08-27 10:54 UTC
From: Andy_Schmidt at HM-Software dot com Assigned: cmb (profile)
Status: Closed Package: Class/Object related
PHP Version: 7.2.5 OS:
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If this is not your bug, you can add a comment by following this link.
If this is your bug, but you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: Andy_Schmidt at HM-Software dot com
New email:
PHP Version: OS:

 

 [2018-05-08 15:37 UTC] Andy_Schmidt at HM-Software dot com
Description:
------------
According to PHP's manual:
http://php.net/manual/en/language.oop5.decon.php
the signature of the __destruct method is:

void __destruct ( void )

Consequently, the following syntax would be correct for 7.2, now that a "void" type hint is available:

function __destruct(): void {}


Actual result:
--------------
PHP Fatal error:  Destructor __destruct() cannot declare a return type

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-05-08 15:50 UTC] requinix@php.net
-Summary: _destruct should permit "void" as return type +Summary: __construct/destruct do not have return types -Status: Open +Status: Verified -Type: Bug +Type: Documentation Problem -Package: PHP Language Specification +Package: Class/Object related
 [2018-05-08 15:50 UTC] requinix@php.net
Constructors and destructors do not have the concept of a return type. The docs showing anything at all, even void, is incorrect.
 [2018-05-08 16:39 UTC] cmb@php.net
> Constructors and destructors do not have the concept of a return
> type.

The same is true for some of the other magic methods (e.g.
__wakeup()).
 [2018-05-08 16:47 UTC] requinix@php.net
-Summary: __construct/destruct do not have return types +Summary: __construct/destruct/clone do not have return types
 [2018-05-08 16:47 UTC] requinix@php.net
True, but __wakeup allows for a void return type. Which I don't mind because its counterpart __sleep does have a return type.

To me it's more the fact that __construct/destruct are particularly special methods and explicitly disallow return types. __clone too, now that I look at the list.
 [2018-05-08 17:05 UTC] Andy_Schmidt at HM-Software dot com
-Status: Verified +Status: Verifiedo
 [2018-05-08 17:05 UTC] Andy_Schmidt at HM-Software dot com
I understand that some methods had always implicitly disallowed return values before there had been a syntax to do so explicitly. The hard syntax error certainly was proper before 7.1. 

However, this is 2018. Why would we still force occasional PHP users from having to memorize the signature for each and every magic method?

Now that "void" is a type hint, it seems that an author writing self-documenting code (for the benefit of less-versed coworkers) should not be penalized with run-time errors for explicitly defining VOID?

I respectfully suggest that with 7.1 and higher, the message category 
"... cannot declare a return type" 
should simply recognize the now-available type "void" as being a perfectly expression of the implicit rule!
 [2018-05-08 17:08 UTC] requinix@php.net
-Status: Verifiedo +Status: Verified
 [2018-05-08 17:08 UTC] requinix@php.net
https://www.google.com/search?q=why+dont+constructors+have+return+types

This isn't about method signatures. This is about what constructors, destructors, and cloning represent. The fact that PHP allows you to specify their behavior using a syntax that resembles that of normal methods is besides the point.
 [2018-05-08 17:27 UTC] requinix@php.net
> using a syntax that resembles that of normal methods is besides the point.
Hmm, okay, poor choice of words there, but what I'm trying to say is that for these three methods return types do not make sense. Because there are no return values. Not in the sense of "this function isn't returning a value" but more "this function is incapable of using return values in the first place".

Other languages:

C# and Java don't have types.
> class Example { public Example() { } }

Python 3 does support a return type on __init__ but for reasons I don't quite understand.
https://www.python.org/dev/peps/pep-0484/#id13
> (Note that the return type of __init__ ought to be annotated with -> None. The reason for this is subtle. If
> __init__ assumed a return annotation of -> None, would that mean that an argument-less, un-annotated __init__ method
> should still be type-checked? Rather than leaving this ambiguous or introducing an exception to the exception, we
> simply say that __init__ ought to have a return annotation; the default behavior is thus the same as for other
> methods.)
I can't tell what ambiguity they're talking about, but I suspect it doesn't apply to PHP since return types are invariant.
(There's also __new__ but that's more of a factory method than a constructor.)

Meanwhile Ruby has constructors but no return types, and Perl has return types but no constructors.
 [2018-05-08 20:55 UTC] cmb@php.net
> I can't tell what ambiguity they're talking about, but I suspect
> it doesn't apply to PHP since return types are invariant.

It seems to me this “ambiguity” is actually what this discussion
is about: if no return type annotation/declaration would be given,
should return statements be checked, or not?  In my opinion, it
does not make much sense, though, to make a constructor special so
that only a None/void return type annotation/declaration would be
accepted, rather than to make a constructor special by not
allowing to specify any return type annotation/declaration, in the
first place.

FWIW: JavaScript's constructor functions are a notable exception
to the no return type, since `new Foo` may return a `Bar`.

Anyhow, I don't think it is useful to have a lengthy discussion
here; the internals mailing list would be more suitable.
 [2021-08-27 10:54 UTC] cmb@php.net
-Summary: __construct/destruct/clone do not have return types +Summary: __construct/__destruct must not have return types -Assigned To: +Assigned To: cmb
 [2021-08-27 10:54 UTC] cmb@php.net
Actually, this discussion happend in the meantime[1], and while
declaring the return type of __clone() as void, the notion of
declaring return types for __construct() and __destruct() has been
declined for reasons[2].

This has been documented the magic methods[3]:

| If type declarations are used in the definition of a magic
| method, they must be identical to the signature described in this
| document. Otherwise, a fatal error is emitted. Prior to PHP 8.0.0,
| no diagnostic was emitted.

This doesn't properly cater to __construct() and __destruct(),
though.

[1] <https://externals.io/message/109542>
[2] <https://externals.io/message/109542#109638>
[3] <https://www.php.net/manual/en/language.oop5.magic.php>
 [2021-08-27 11:04 UTC] git@php.net
Automatic comment on behalf of cmb69
Revision: https://github.com/php/doc-en/commit/3926279f825d418fdd2e7079968507d8b0c62b7d
Log: Fix #76311: __construct/__destruct must not have return types
 [2021-08-27 11:04 UTC] git@php.net
-Status: Verified +Status: Closed
 [2021-08-28 04:37 UTC] git@php.net
Automatic comment on behalf of mumumu
Revision: https://github.com/php/doc-ja/commit/f90c1c2c1eb6f39e83c2bf3f60b8ae0a7f719082
Log: Fix #76311: __construct/__destruct must not have return types
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 23:01:26 2024 UTC