Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:70154 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 33298 invoked from network); 15 Nov 2013 10:08:04 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 15 Nov 2013 10:08:04 -0000 Authentication-Results: pb1.pair.com smtp.mail=php@tutteli.ch; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=php@tutteli.ch; sender-id=pass Received-SPF: pass (pb1.pair.com: domain tutteli.ch designates 80.74.154.78 as permitted sender) X-PHP-List-Original-Sender: php@tutteli.ch X-Host-Fingerprint: 80.74.154.78 ns73.kreativmedia.ch Linux 2.6 Received: from [80.74.154.78] ([80.74.154.78:37943] helo=hyperion.kreativmedia.ch) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 19/81-25016-282F5825 for ; Fri, 15 Nov 2013 05:08:03 -0500 Received: (qmail 6838 invoked from network); 15 Nov 2013 11:07:59 +0100 Received: from heim-032-99.raab-heim.uni-linz.ac.at (HELO RoLaptop) (193.171.32.99) by ns73.kreativmedia.ch with (AES128-SHA encrypted) SMTP; 15 Nov 2013 11:07:59 +0100 To: "'Chris London'" , References: In-Reply-To: Date: Fri, 15 Nov 2013 11:07:56 +0100 Message-ID: <000501cee1ea$8eb3fbc0$ac1bf340$@tutteli.ch> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Mailer: Microsoft Outlook 14.0 Thread-Index: AQG2wyOXY4ErA7I4tVQsF4tpMC9iNJpWSJkw Content-Language: de-ch Subject: RE: [PHP-DEV] Proposal: Type Casting User Classes From: php@tutteli.ch ("Robert Stoll") Hi Chris > -----Original Message----- > From: Chris London [mailto:me@chrislondon.co] > Sent: Thursday, November 14, 2013 7:40 PM > To: internals@lists.php.net > Subject: [PHP-DEV] Proposal: Type Casting User Classes > > Hey everyone, > > I want to get a feel for something I would like to implement into PHP core. > I would like to be able to cast objects to my own class types. Similar to > already available PHP syntax: > > $foo = (string) $bar; > > The syntax would look like this: > > $foo = (\My\FooObject) $bar; > > It would also support: > > $foo = ( (\My\FooObject) $bar )->myFooObjectFunction(); > > I'm still trying to decide what would happen internally and I would like some > feedback. I'm thinking of 3 different things it could do: > > 1) Directly change the class type, functionally equivalent to: > > function castType($object, $type) { > return unserialize(preg_replace("/^O:[0-9]+:\"[^\"]+\":/i", > "O:".strlen($type).":\"$type\":", serialize($object))); > } [Robert Stoll] Seems a bad idea to me. Would be slow and is not really a cast but a conversion. > 2) Throw a fatal error if the object doesn't match the type trying to be cast. [Robert Stoll] That's what I would expect from a runtime type checking mechanism > 3) Add a new static magic method called __cast() that would allow the > developer to decide what happens. Like this: > > namespace \My; > > class FooObject { > public static function __cast($foo) { > // Do stuff here > return new FooObject; > } > } [Robert Stoll] This is interesting but goes beyond casts and is a conversion mechanism again. But would be truly helpful for utility classes like Email etc. (there was already another discussion about this feature as far as I remember) > I'm willing to implement this myself if everybody else likes this idea. > Thanks! > > Chris London You might be interested in my project Type-Safe PHP (TSPHP): http://tsphp.tutteli.ch It is far from a real release candidate but that's mostly because I am the only developer contributing to this project so far (and unfortunately I do not really have time lately). Other contributors are welcome ;-) TSPHP would substitute object casts for you (without the performance penalty of an additional function call and the use of is_a) but you could emulate it with a function this way: function cast($object, $type){ if($object == null || \is_a($object,$type)){ return $object; }else{ trigger_error('cast error, $object was not of type '.$type); } } I have chosen trigger_error to be consistent with (int), (string) etc. which trigger an error as well if something goes wrong. Replace it with a throw if you like. And use it like this - a one liner as well ;-) class A{} class B extends A{} $a = new B(); $a = cast($a, "A"); Of course, $a will not change its type but is guaranteed to be of type A. There was a discussion about down casting in another email. That's not possible with this function since it is a cast and not a conversion. Btw the Liskov Substitution Principle tells that you should be able to replace your class with your sub-class without breaking things but not that a class magically can do the same thing as a sub-class. But you were probably thinking about a conversion/mapping and fair enough, that might be possible but there are a lot of cases where this is not as straight forward as you may think. Cheers, Robert