hi, On Thu, Nov 17, 2011 at 10:12 PM, Ralph Schindler <ra...@ralphschindler.com> wrote: > Hey All, > > Concerning RC1, __construct() and https://wiki.php.net/rfc/prototype_checks > > I think we need to round out this discussion on the __construct() signature > checking in 5.4. The current behavior (RC1) feels very wrong with respect > to PHP's class based, single inheritance, multiple interface, no method > overloading, allowed method-overriding nature. > > Constructors themselves, specifically in PHP, are not explicitly statically > marked, but are "special" (even though they are part of the instance API, > and are callable- we'll consider this an implementation detail). In > general, constructor signatures have never been (and rightfully so) governed > by the LSP. Why? For a few reasons: > > 1) before calling new(), you actually don't have a subtype (yet)- the > subtype is a *product* of new() > > 2) when you call new(), you know the exact subtype you're dealing with. > > 3) only subtypes who implement or override __construct() can know how to > prepare a stateful subtype. In other words, parents can't know how to > create subtypes who implement __construct() and subtypes shouldn't be > concerned with the implementation details of how a parent creates types when > a subtype has overridden __construct(); > > 4) LSP deals with behaviors and expectations of types (read: objects), > since the constructor is generally considered "static" in nature, a form of > factory specific to the type its defined within, and since in PHP you can't > do (SomeClass instanceof SomeType) and since (is_a('SomeClass', 'SomeType') > doesn't make much sense in the context of classes), the constructor is not > subject to instance "behavior" rules. > > In general, developers shouldn't be putting abstract constructors inside an > abstract class nor should they be putting constructors inside interfaces- > this is a well accepted bad practice. (Neither c# or java allow this- of > course they do have the ability to overload methods in classes for the > record. In fact, static methods are not allowed either.) > > That said, we really should consider removing this limitation from > constructor signature checking. Not only is it a BC break, it doesn't make > sense in the context of PHP.
<?php class A { function __construct($a, $b) { } } class B extends A{ function __construct($a) { } } works. While the following does not: Abstract class A { abstract function __construct($a, $b); } class B extends A{ function __construct($a) { } } does not and it is per definition correct. Abstract defines the signature and ensures that the signature are 100% the same. We had a long discussion about that a couple of months ago. The main disagreement was about the interpretation of the definition of abstract. Abstract clearly talks about signature matching, as I (and quite a lot of other) read it. Cheers, -- Pierre @pierrejoye | http://blog.thepimp.net | http://www.libgd.org -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php