Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:82746 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 91090 invoked from network); 15 Feb 2015 20:05:07 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 15 Feb 2015 20:05:07 -0000 Authentication-Results: pb1.pair.com header.from=rowan.collins@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=rowan.collins@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 74.125.82.42 as permitted sender) X-PHP-List-Original-Sender: rowan.collins@gmail.com X-Host-Fingerprint: 74.125.82.42 mail-wg0-f42.google.com Received: from [74.125.82.42] ([74.125.82.42:49542] helo=mail-wg0-f42.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id D7/B0-21457-2FBF0E45 for ; Sun, 15 Feb 2015 15:05:06 -0500 Received: by mail-wg0-f42.google.com with SMTP id n12so9270411wgh.1 for ; Sun, 15 Feb 2015 12:05:02 -0800 (PST) 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=+RIPUaMjmC5K4Rz6n+ZoYfY7eLdcWla/f2Xps5EDHXo=; b=T8RnL4e92xwzMLXOFPlxm3kf9nhhN6RDDxJuKJ+KxnNrE1MVyZEOuUA75ANho0QOEz iPb4scq/jUd8rii3lEhSRrNyeHZtpHxZhh6Td9vy+FfktYKOWBbspROcZK+xJTfrHZjP wfyzfVWeqi8k4LbCjW11QlKTF5+x8B30Bzc0M2oCDp7LbKk9ZRP3xMb4KRmAiUip+bpn W9+GCP1aDmZTF+39kBlrPDAjo40Xwd8Qhw39RP9AfNMLgud7zwpgzGF/LV7wHzgBoXLB EpiiMj4K6lU2DCwnklXW8zOSKsYFsGvnfOzGOqxhYxuPLZMWD2YB23Y/t74nXVQlxW7v 1dwA== X-Received: by 10.180.240.169 with SMTP id wb9mr39679329wic.83.1424030702485; Sun, 15 Feb 2015 12:05:02 -0800 (PST) Received: from [192.168.0.2] (cpc68956-brig15-2-0-cust215.3-3.cable.virginm.net. [82.6.24.216]) by mx.google.com with ESMTPSA id gz3sm301487wib.1.2015.02.15.12.05.01 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 15 Feb 2015 12:05:01 -0800 (PST) Message-ID: <54E0FBE0.10301@gmail.com> Date: Sun, 15 Feb 2015 20:04:48 +0000 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Thunderbird/31.4.0 MIME-Version: 1.0 To: internals@lists.php.net References: In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [PHP-DEV] A modest proposal: __contructStatic From: rowan.collins@gmail.com (Rowan Collins) On 15/02/2015 19:04, Patrick Schaaf wrote: > In our codebase we have one set of classes where it was very useful to be > able to call the same methods both statically and nonstatically: a set of > wrapper classes over phpredis where subclasses "know" which set of redis > servers to talk to (plus other config like retry strategies and timeouts). > In most cases calling code does not need to be concerned with these details > and just calls methods like red_global::get() or red_local::put(). > > By neccessity the implementation of this class set, must make use of both > __call() and __callStatic() magic methods, with both then dispatching to a > delegate phpredis instance, and in the case of __callStatic(), making > up-front a singleton like "new self" once. For a set of additional helper > methods (not present on the underlying phpredis) I additionally have a > special mapping array of real method names to internal implementation names. This sounds to me like you should just be using the Singleton pattern, at which point you need no magic calls at all. It can even be done as a subclass of an existing non-static class: class MyRedis extends Redis { private static $singleton; public static function singleton() { if ( is_null(self::$singleton) ) { self::$singleton = new self; // may need parameters here } return self::$singleton; } // Other methods can go here, just like a normal subclass } // Now wherever in the code you want the default instance, just use this: $value = MyRedis::singleton()->get($key); MyRedis::singleton()->someCustomAction($anotherKey); The nice thing about an explicit Singleton is you can migrate to Dependency Injection (call "$redis = MyRedis::singleton()" and start passing the instance around, until you get to the point where it is only called once), or to a cleverer factory / service locator (store more than one instance in different static variables or a keyed array, to connect to different stores for different purposes). Making static calls implicitly access a singleton seems like it would make code harder to read, and harder to extend, in exchange for typing a few characters on each call (you could call it something shorter, like "::inst()" if you valued brevity) so a -1 from me. Regards, -- Rowan Collins [IMSoP]