Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:55485 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 11753 invoked from network); 17 Sep 2011 18:00:21 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 17 Sep 2011 18:00:21 -0000 Authentication-Results: pb1.pair.com smtp.mail=tyra3l@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=tyra3l@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.213.42 as permitted sender) X-PHP-List-Original-Sender: tyra3l@gmail.com X-Host-Fingerprint: 209.85.213.42 mail-yw0-f42.google.com Received: from [209.85.213.42] ([209.85.213.42:34799] helo=mail-yw0-f42.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id AA/26-05466-330E47E4 for ; Sat, 17 Sep 2011 14:00:20 -0400 Received: by ywa8 with SMTP id 8so4113977ywa.29 for ; Sat, 17 Sep 2011 11:00:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type:content-transfer-encoding; bh=Z7G2DUHnTQVV5lLNZa6swzlMwDvj33XS+2iE6HUSQ3I=; b=hJ7T1JT95MieRheGfgnWSq78jWL0r8OiNDlnJS63PzY75wXnHS69tiqWwbj7JduKbL WWaSQC51QwkzcpRNMm0Mpi3JhCcYqvC9PR3YeMA4qwojVIz8kk7byNBD5KjuDI6MYGlj xozqQM8ujTgUAbANspJvXz0+idxHo2arRQTxQ= MIME-Version: 1.0 Received: by 10.146.134.35 with SMTP id h35mr749942yad.3.1316282413125; Sat, 17 Sep 2011 11:00:13 -0700 (PDT) Received: by 10.147.125.13 with HTTP; Sat, 17 Sep 2011 11:00:13 -0700 (PDT) In-Reply-To: References: Date: Sat, 17 Sep 2011 20:00:13 +0200 Message-ID: To: Etienne Kneuss Cc: Laruence , devis@lucato.it, internals@lists.php.net, RQuadling@gmail.com, Nikita Popov Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] __constructor parameter limitations. From: tyra3l@gmail.com (Ferenc Kovacs) >> =C2=A0do you know any reason for this? >> > > The reason for this is simply that B must act like A since every B object= is > also an object of A. > > The reason for restricting the method signature in the Subclass is to guarantee that an instance of a Subclass should work where an instance of the Superclass is expected. I think that this can be achieved with much weaker rules than expecting that the method in the Subclass has the exact signature as the Superclass. For example we do allow overriding visibility, but only weakening it(eg. private->protected or protected->public is allowed but public->protected isn't), else there could be cases where using the instance of the Superclass works, but the Subclass won't. Another thing that we should take into account: php is no java, so we don't have to require exactly matching method signature, as in php the method name cannot be ambiguous(we don't support declaring methods with the same name but different argument signature), and because of this passing more arguments than it was declared also supported in the userland functions/methods. So based on this, the following cases are which would make a Subclass incompatible with it's Superclass: - tightening visibility (we already restrict this) - declaring more arguments in the Subclass than in the Superclass, and having no default value for those. - declaring different typehints in the Subclass than it was declared in the Superclass. theoretically we could also allow changing the typehinting where it makes sense (for example it would be safe to allow changing the typehint from Foo to Bar if Bar extends/implements Foo), but I think that would require too much work, so I'm fine with requiring the same typehint if it was present in the parent. - removing default values from the arguments. (declaring the same argument as in the Superclass, but without default value, while the Superclass declared it with default value) the following cases would be allowed to change the method signature without making the Subclass incompatible with it's Superclass: - the Subclass could declare fewer arguments than it's Superclass. this could sound wrong, but as I mentioned, the engine allows passing more arguments, than it was declared, so Subclass would work everywhere where the Superclass is expected, and the arguments can be accessed through func_get_args. of course it would allow someone to shot himself in the foot(if he chose not to fetch the arguments from the method body), but that can happen already(for example. the Subclass can return different type than what the Superclass would, or it could throw different Exceptions, or just return some bogus value, etc.). - the Subclass could declare more argument than it's Superclass, as long, as the additional argument are having default values. - the Subclass could declare arguments without typehints which were declared with typehints in the Superclass. - the Subclass could declare arguments with default values which were declared without default values in the Superclass. for example: class super{ public function init(array $a=3Dnull){ } } could be extended like: // one additional argument, but it has default value, so it is fine class sub extends super{ public function init(array $a=3Dnull, $b=3Dfalse){ } } // same argument but without the typehint class sub extends super{ public function init($a=3Dnull){ } } // fewer arguments class sub extends super{ public function init(){ } } // remove the typehint class sub extends super{ public function init($a=3Dnull){ } } but the followings are all invalid: // invalid, because it removes the default value class sub extends super{ public function init(array $a){ } } // invalid, because the additional argument doesn't have a default value class sub extends super{ public function init(array $a, $b){ } } // invalid, because changes the typehint class sub extends super{ public function init(StdClass $a, $b){ } } ps: the invalid signature should generate catchable fatal error, not fatal error imo, we are using fatal error many places where it would be reasonable to use Catchable fatal error, as Fatals should be only used where the Engine is left in an unstable state, or which cannot be recovered from. --=20 Ferenc Kov=C3=A1cs @Tyr43l - http://tyrael.hu