php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #64454 It is possible to directly call the magic method "__construct".
Submitted: 2013-03-19 12:45 UTC Modified: 2013-03-22 16:19 UTC
Votes:2
Avg. Score:5.0 ± 0.0
Reproduced:2 of 2 (100.0%)
Same Version:2 (100.0%)
Same OS:1 (50.0%)
From: wolters dot fl at gmail dot com Assigned:
Status: Wont fix Package: Class/Object related
PHP Version: 5.4.13 OS: Microsoft Windows Version 6.2.9
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 you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: wolters dot fl at gmail dot com
New email:
PHP Version: OS:

 

 [2013-03-19 12:45 UTC] wolters dot fl at gmail dot com
Description:
------------
It is possible to directly call the magic method "__construct". This should NOT be possible, since one cannot create immutable objects with the current behaviour.

In addition, a direct call to the magic method "__clone" is not possible and raises an "\E_FATAL". Both magic methods deal with object creation, so the behaviour is inconsistent between them.

I am using "php-5.4.13-nts-Win32-VC9-x86" on Microsoft Windows Version 6.2.9 x64(Windows 8 64 bit).

Test script:
---------------
https://gist.github.com/FlorianWolters/5195734

Expected result:
----------------
The method call:

$example->__construct();

should raise an "\E_FATAL" with the following message:

"Cannot call __construct() method on objects - use 'new <Class>' instead in [...] on line 21"


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-03-22 04:18 UTC] laruence@php.net
-Status: Open +Status: Wont fix
 [2013-03-22 04:18 UTC] laruence@php.net
PHP's __construct, actually, is not creating object, it decorate the object after 
it was created.

so,  even you directly call to $obj->__construct, then no new instance was create.

so a workaround is you can exam some property you set to see whether that is a 
double constructing or not.


thanks
 [2013-03-22 07:03 UTC] nikic@php.net
Additionally to what laruence said, one should also point out that __construct is quite commonly called directly in the form of parent::__construct().
 [2013-03-22 16:19 UTC] wolters dot fl at gmail dot com
Yes, I do understand that "__construct" is an interceptor method and can be called from a subclass directly via "parent::__construct", but:

1. "parent::__construct" is a "static" method call which can occur inside of a class only.
2. The problem is, that it is possible to call "$obj->__construct" from outside a class. I could understand the behaviour if the call would be allowed from the inside of a class only.

Imho, calling "__construct" directly should ONLY be possible from the INSIDE of a class. Plus, such a call MUST be STATIC (otherwise a PHP error is raised).

From a clients PoV, __construct is a member method (similar to __clone):
* __clone is invoked via the "clone" operator.
* __construct is invoked via the "new" operator.

I don't see the reason, why there is a difference in that behaviour. I do not know much about the internals (C code) of the interceptor methods, but from the clients PoV these distinctions in behaviour are confusing.

PS: I also updated my example at https://gist.github.com/FlorianWolters/5195734 to emphasize this.
 [2013-03-22 16:51 UTC] nikic@php.net
1. parent::__construct() is not a static method call, its a scoped call. It only says: Do $this->__construct() in the "parent" context.

2. Could you explain why it is a problem? What issues are there with calling __construct() from outside the class? I don't see any. I don't see much use either. One possible use would be calling it in a context where the constructor is not called by itself, e.g. one could call __construct() after an unserialization or something.

Really, I don't get why you want to forbid this. We don't usually prohibit direct calls to magic methods and I don't see why we should do so in this particular instance. Quite honestly, I more wonder why the call to __clone() is not allowed.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sat May 03 00:01:28 2025 UTC