I just realised that the following is valid php code:
class Foo {
function __construct() {
echo "constructor called\n";
}
}
$f = new Foo();
$f->__construct();
Output:
constructor called
constructor called
I would have expected the second call to __construct() to yield an error.
Has this been discussed before? In that case, was it decided to go
with this behaviour or is it purely accidental? Are there perhaps some
implementation issues in preventing the second call to __construct()?
--
troels
2009/7/2 troels knak-nielsen troelskn@gmail.com:
Has this been discussed before? In that case, was it decided to go
with this behaviour or is it purely accidental? Are there perhaps some
implementation issues in preventing the second call to __construct()?
Magic methods can always be called directly because they must be
declared public to work. I don't see a reason why to disallow it, if a
user manually executes a magic method they should be knowing what they
are doing and remember that there might be side-effects with there
code.
--
regrads,
Kalle Sommer Nielsen
kalle@php.net
Excerpts from troels knak-nielsen's message of Thu Jul 02 10:14:18 -0400 2009:
I would have expected the second call to __construct() to yield an error.
Why should it? Especially since this is idiomatic code:
class A {
public function __construct($a) {
$this->a = $a;
}
}
class B extends A {
public function __construct($a, $b) {
$this->b = $b;
parent::__construct($a);
}
}
__construct doesn't do anything like allocate memory. It just happens
to get called when we do "new B(1, 2)"
Cheers,
Edward
Excerpts from troels knak-nielsen's message of Thu Jul 02 10:14:18 -0400 2009:
I would have expected the second call to __construct() to yield an error.
Why should it? Especially since this is idiomatic code:
class A {
public function __construct($a) {
$this->a = $a;
}
}class B extends A {
public function __construct($a, $b) {
$this->b = $b;
parent::__construct($a);
}
}
In that example, the object instance is not initialised when
parent::__construct() is called.
__construct doesn't do anything like allocate memory. It just happens
to get called when we do "new B(1, 2)"
I understand that. It's not a technical issue - It's more a matter of
language semantics. Constructors are used for initializing state on an
object. Basically, this behaviour makes it impossible to implement
immutable objects in php. It's not a huge deal - I don't remember ever
seen __construct() called directly.
--
troels
Excerpts from troels knak-nielsen's message of Thu Jul 02 10:55:48 -0400 2009:
I understand that. It's not a technical issue - It's more a matter of
language semantics. Constructors are used for initializing state on an
object. Basically, this behaviour makes it impossible to implement
immutable objects in php. It's not a huge deal - I don't remember ever
seen __construct() called directly.
Au contraire, you can employ this little trick:
class A {
private $a;
private function __construct($a) {
$this->a = a;
}
public function make($a) {
return new A($a);
}
}
But I agree; stab anyone who is doing $foo->__construct(). Except for
testing. Testing is ok.
Cheers,
Edward
troels knak-nielsen wrote:
Excerpts from troels knak-nielsen's message of Thu Jul 02 10:14:18 -0400 2009:
I would have expected the second call to __construct() to yield an error.
Why should it? Especially since this is idiomatic code:class A {
public function __construct($a) {
$this->a = $a;
}
}class B extends A {
public function __construct($a, $b) {
$this->b = $b;
parent::__construct($a);
}
}In that example, the object instance is not initialised when
parent::__construct() is called.__construct doesn't do anything like allocate memory. It just happens
to get called when we do "new B(1, 2)"I understand that. It's not a technical issue - It's more a matter of
language semantics. Constructors are used for initializing state on an
object. Basically, this behaviour makes it impossible to implement
immutable objects in php. It's not a huge deal - I don't remember ever
seen __construct() called directly.--
troels
Hi,
__construct can be private or protected, it just requires implementing a
factory() or singleton() method to retrieve the immutable object.
Greg
2009/7/2 troels knak-nielsen troelskn@gmail.com:
[snip] ... - I don't remember ever
seen __construct() called directly.
Its commonly done when extending reflection for example, or to
populate the Exception class constructor when extending it:
<?php
class TestException extends Exception
{
public function __construct($code, $message)
{
$this->code = (integer) $code;
parent::__construct($message);
}
}
?>
Or more complex constructors without having to re-implement their
logic / handling of constructing the object.
--
regrads,
Kalle Sommer Nielsen
kalle@php.net