Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:84655 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 23311 invoked from network); 12 Mar 2015 19:48:46 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 12 Mar 2015 19:48:46 -0000 X-Host-Fingerprint: 194.166.179.101 194-166-179-101.adsl.highway.telekom.at Received: from [194.166.179.101] ([194.166.179.101:14992] helo=localhost.localdomain) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 98/26-24603-C9DE1055 for ; Thu, 12 Mar 2015 14:48:46 -0500 Message-ID: <98.26.24603.C9DE1055@pb1.pair.com> To: internals@lists.php.net Date: Thu, 12 Mar 2015 20:45:30 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-Version: 1.0 References: <6D.2C.32765.10EC0055@pb1.pair.com> <5500D967.5040800@gmail.com> <13.69.64353.73451055@pb1.pair.com> <5501876C.3020107@gmail.com> <3D.85.42021.3E7A1055@pb1.pair.com> <5501B77D.5010800@gmail.com> <85.D1.24603.247C1055@pb1.pair.com> <5501D328.9040800@gmail.com> In-Reply-To: <5501D328.9040800@gmail.com> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Posted-By: 194.166.179.101 Subject: Re: [PHP-DEV] static constructor From: mail@deroetzi.de (Johannes Ott) Am 12.03.2015 um 18:55 schrieb Rowan Collins: > Johannes Ott wrote on 12/03/2015 17:05: >> Am 12.03.2015 um 16:57 schrieb Rowan Collins: >>> Johannes Ott wrote on 12/03/2015 14:51: >>>> That is nearly like initializing a class constant, but in my opinion a >>>> constant should not have a "complex" algorithm (For example conditions >>>> or read from filesystem). That should be encapsulated inside a proper >>>> method body. >>> I agree, but as such, I think that method should be called somewhere by >>> the code, even if only by a DI container, not happen automagically and >>> slurp in data from global state. >>> >> It is called somewhere in the code namely inside the static >> constructor :D > > What I meant is that it is not executed by any piece of code the user > writes, but directly by the engine based on a magic hook. > Yes but thats why it is called magic method, isn't it ;) No serious if it is clearly defined what the magic method __static() does and when it is invoked, it should be okay. All of the magic methods are doing like this. >>> Incidentally, note that a recent RFC to add the ability to declare a >>> class as static failed by 12 votes to 5 - >>> https://wiki.php.net/rfc/abstract_final_class - and much of the >>> discussion was around static implementations being generally inferior to >>> instances, so I'm not alone in challenging designs that rely on them. >>> >> I will check the rfc later but "static class" sounds strange. I had time to read the linked rfc now. If I understand it right that rfc Means a Util-class-pattern for util-classes which should not be extendable. I don't see the sense of that now, why I util class with only static methods which typically is defined as abstract should not be extendable by other, I cannot remember to have this use cased in my 15 years of OOP-programming but okay maybe there are such use cases. But my proposal is another one see my next comment on your comment below. > > Basically, all your examples imply classes that consist only of static > members - they're not using static helpers to create instances, they're > using them *instead of* instances. This was what was mean by "static > class" in that proposal. Personally, I was in favour of that, since I > think such classes do exist, and a syntax for declaring them would be > useful, but the most common argument against was that we should be > finding ways for people to not need such classes, rather than supporting > them better. This proposal sounds like it's adding facilities to classes > that belong on objects, or ... somewhere else. > Okay thats a point I have to clearify I see, maybe my examples where to much shorten by me. In my examples I'm showing only the initialize parts of the classes, the initialized properties are used all over the class in static as well in non-static context. For use case 1 the LogAdapter for example is a singleton instance per class, that's why in my understanding of dependcy Injection it is not working with it (correct me please if I'm wrong). And this singleton is used to log in all methods of the class/object. Surely I would be able to get the specializied Singleton instance with doing some code like the following two examples: Example 1 (As I already would be prefered solution for me if I use the Logger only in a few of the methods and not in the majority of it): class A { private static $LOG; private static function initLogger() { if (self::$LOG = null) { self::$LOG = LogAdapter::getLogger(self::class); } } public static function a() { self::initLogger(); self::$LOG->debug(); .... self::$LOG->error(); } public function b() { self::initLogger(); ... self::$LOG->error(); } ... } or Example 2: (which is in my opinion really hard to read and to much to write) class A { public static function a() { LogAdapter::getLogger(self::class)->debug(); .... LogAdapter::getLogger(self::class)->error(); } public function b() { ... LogAdapter::getLogger(self::class)->error(); } ... } With my solution of a static constructor it would look like this. class A { private static $LOG; private static function __static() { self::$LOG = LogAdapter::getLogger(self::class); } public static function a() { self::$LOG->debug(); .... self::$LOG->error(); } public function b() { ... self::$LOG->error(); } ... } On huge classes with 10 or more methods all using the LOG reference this is in my opinion the cleanest and shortest solution. I hope I could make the example more clear?! If you need more examples please let me know. Regards -- DerOetzi