Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:84632 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 59149 invoked from network); 12 Mar 2015 12:23:33 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 12 Mar 2015 12:23:33 -0000 Authentication-Results: pb1.pair.com smtp.mail=rowan.collins@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=rowan.collins@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.212.175 as permitted sender) X-PHP-List-Original-Sender: rowan.collins@gmail.com X-Host-Fingerprint: 209.85.212.175 mail-wi0-f175.google.com Received: from [209.85.212.175] ([209.85.212.175:38729] helo=mail-wi0-f175.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 4E/B2-42021-44581055 for ; Thu, 12 Mar 2015 07:23:33 -0500 Received: by widex7 with SMTP id ex7so46480525wid.3 for ; Thu, 12 Mar 2015 05:23:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:subject:references :in-reply-to:content-type:content-transfer-encoding; bh=UZMZLzA7owTC9kaStEzc58l5GQDfsXRpofjdqdF4rIA=; b=O+kB3mJ+0eqyJePrNnBZ7CK3AHvb1qWIRx5zlMNRJ4Z53aP81OjL+z8pWcWLwA6Tud G+QZSCJ5kY6FCycMHvZEgYjn31ESBB1M1VZacypzE2eac5IM0t0TVzDaBuWOSRcy/lbS y6fUQBd0MixDkE7zSHcl9jYGhWA7euw/+/63ZiD7G5gdgN3OwwTlud0vkGi1nLcbe5bJ TvjH93GCCbS5giDh3Dd6lnB33QfgCtUGSWh4m8lj3dz+ItPVNY30axe8ad0DYpc4z/9d 1sNOddmtNBTVj/MJe/t1ZX2L04HuLp48bOYM1CXghlNz2ynpFawl2wamlbZfLucTmnrh aEdA== X-Received: by 10.180.84.133 with SMTP id z5mr87327414wiy.25.1426163009888; Thu, 12 Mar 2015 05:23:29 -0700 (PDT) Received: from [192.168.0.159] ([62.189.198.114]) by mx.google.com with ESMTPSA id vh8sm9811138wjc.12.2015.03.12.05.23.28 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 12 Mar 2015 05:23:29 -0700 (PDT) Message-ID: <5501851D.8020704@gmail.com> Date: Thu, 12 Mar 2015 12:22:53 +0000 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-Version: 1.0 To: internals@lists.php.net References: <6D.2C.32765.10EC0055@pb1.pair.com> <5500D967.5040800@gmail.com> <1806447.6ZrGY6hLx0@rofl> In-Reply-To: <1806447.6ZrGY6hLx0@rofl> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [PHP-DEV] static constructor From: rowan.collins@gmail.com (Rowan Collins) Patrick Schaaf wrote on 12/03/2015 08:40: > On Thursday 12 March 2015 00:10:15 Rowan Collins wrote: >> On 11/03/2015 23:21, Johannes Ott wrote: >> >>> The purpose of this suggestion is to introduce a static constructor, >>> which is called before the first call to class either static or >>> non-static to initialize some static properties which are needed by the >>> class. >> Can you give an example use case for when this would be useful? I'm >> struggling to think of one for which there isn't already an established >> coding pattern... > It's useful everywhere you now have more than one method starting > > if (!static::$is_initialized) static::initialize_me(); I suspect that most places where this occurs, there are other ways to eliminate it than adding magic pre-initialisation. If a class has lots of static methods all depending on some state being initialised, maybe they just shouldn't be static - they should be instance members of a Singleton or Dependency Injected object. Or maybe they're accessing members directly which would be better hidden behind an accessor method which loads some data and "caches" its result. > Some examples from our codebase: > > - a session wrapper class, hiding $_SESSION behind setter/getter methods, > where the static class initialization determines which cookie to use, > depending on some global feature flags, and which session backend to use, > depending on current availability. (main purpose, apart from clean calling > side code just using the setters/getters, is to get the lazy_write > functionality Yasuo tried to introduce recently) This sounds like a job for a Singleton or Dependency-Injected object. The initialisation is a specific action with its own parameters (which you're currently grabbing from global configuration). > - computation of some class properties from others, like doing an array_flip > on one to get a reverse mapping. > > - definition of computed constants, in various places. Partly obsolete now > that class constants support constant expressions, but needed as soon as these > are not really constant. This is the only case that seems valid to me: enums and other types of "computed constant", where the class is just there as a container. > - invariant checks on subclasses, in various places, where concrete subclasses > set up some static properties of a configuration nature, and I want to make > sure in the base class, as early as possible, that the values are consistent > and make sense, avoiding checks spread all over the place in various methods. The question is, why is this whole hierarchy static? If these were instances not definitions, the initialisation is a well-defined event (the constructor), and you can check validity there. Regards, -- Rowan Collins [IMSoP]