Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:67467 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 35098 invoked from network); 23 May 2013 21:24:45 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 23 May 2013 21:24:45 -0000 Authentication-Results: pb1.pair.com smtp.mail=ceo@l-i-e.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=ceo@l-i-e.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain l-i-e.com designates 67.139.134.202 as permitted sender) X-PHP-List-Original-Sender: ceo@l-i-e.com X-Host-Fingerprint: 67.139.134.202 o2.hostbaby.com FreeBSD 4.7-5.2 (or MacOS X 10.2-10.3) (2) Received: from [67.139.134.202] ([67.139.134.202:1270] helo=o2.hostbaby.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id C6/14-16824-B198E915 for ; Thu, 23 May 2013 17:24:45 -0400 Received: (qmail 6365 invoked by uid 98); 23 May 2013 21:24:45 -0000 Received: from localhost by o2.hostbaby.com (envelope-from , uid 1013) with qmail-scanner-2.05 ( Clear:RC:1(127.0.0.1):. Processed in 0.036278 secs); 23 May 2013 21:24:45 -0000 Received: from localhost (HELO www.l-i-e.com) (127.0.0.1) by localhost with SMTP; 23 May 2013 21:24:45 -0000 Received: from webmail (SquirrelMail authenticated user ceo@l-i-e.com) by www.l-i-e.com with HTTP; Thu, 23 May 2013 16:24:45 -0500 Message-ID: <6b642a96e673c29dbaf2f239be15f7f6.squirrel@www.l-i-e.com> Date: Thu, 23 May 2013 16:24:45 -0500 To: internals@lists.php.net User-Agent: SquirrelMail/1.4.21 [SVN] MIME-Version: 1.0 Content-Type: text/plain;charset=iso-8859-1 Content-Transfer-Encoding: 8bit X-Priority: 3 (Normal) Importance: Normal Subject: Cannot call constructor From: ceo@l-i-e.com ("Richard Lynch") Consider this common scenario: I use some OOP library, that is a "black box" and I like it that way. As part of the integration, I need to extend one of the library's classes: class App_bar extends Library_foo{ function __construct(){ //do whatever I need to do here. } } So I write this code, and it works, and I'm happy. Years go by and new releases of the library come out, steadily improving features and fixing bugs etc. But at some point, the library needed a resource in a __construct() somewhere in the ancestry of Library_foo, to perform something at the time of construction. So they re-factored or re-implemented the black box library to have a constructor in Library_foo class, or any of its numerous ancestors. Suddenly my code doesn't work. Maybe the resource is only needed under certain conditions. So their __construct doesn't get called, but nothing bad happens until the circumstances where they need the __construct called. So now I don't just have a bug, I have an intermittent bug. And as much as we all like to think our testing covers 100% of the functionality... I'm tearing my hair out trying to find where things went wrong in code that worked for years. Right now, to avoid this situation, you have to do: if (method_exists(get_parent_class(), '__construct')) parent::__construct(); If you don't check for the method existing, you get: Fatal error: Cannot call constructor ... I don't want to have an intimate knowledge of the internals of the library; just the documented API. That's one of the major reasons for using a library. I would think that as PHP climbs up the chain of "extends" et al, if it never found a parent method, if wouldn't complain about it, much less E_FATAL... I mean, so you didn't find a method that's not there to find. And I should call parent::__construct just in case there is one there, because I don't know, or care, really, how the black box is implemented. So long as the library does what's on the tin (in the docs).