Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:37527 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 10075 invoked from network); 7 May 2008 23:30:07 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 7 May 2008 23:30:07 -0000 Authentication-Results: pb1.pair.com header.from=lew21st@gmail.com; sender-id=pass; domainkeys=bad Authentication-Results: pb1.pair.com smtp.mail=lew21st@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.198.237 as permitted sender) DomainKey-Status: bad X-DomainKeys: Ecelerity dk_validate implementing draft-delany-domainkeys-base-01 X-PHP-List-Original-Sender: lew21st@gmail.com X-Host-Fingerprint: 209.85.198.237 rv-out-0506.google.com Received: from [209.85.198.237] ([209.85.198.237:28362] helo=rv-out-0506.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 7C/00-09232-E7B32284 for ; Wed, 07 May 2008 19:30:06 -0400 Received: by rv-out-0506.google.com with SMTP id g37so583015rvb.23 for ; Wed, 07 May 2008 16:30:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from:to:subject:mime-version:content-type:content-transfer-encoding:content-disposition; bh=QPrGRJ0ZsQeECGWk3+PSWQ1LAkSWItrip/KA47m9M6A=; b=cD0qD4gqW0Mc7N8d17bzZbYaT2Ecbdhx5Et5e25bbj5l1yqVTcRkqY0g3kzXTz0Xrkcb2/fOXywNjk2A7hWop08+r9L3PPRi0hlcNomWrmhFaFHmoDBPDsUc/jGlmzyddMNnD83VhnZ1ChvwmP45fFU8BuVvjpNmrIC0n9T/2Ws= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:to:subject:mime-version:content-type:content-transfer-encoding:content-disposition; b=SoEYccmx/D19JY2tjhceKXkmzIz7zltuIgV0wIrEnfPNLGLXi7CFskywLKX/joflQ/5Lokt/beZD6vuMQMJF6UA3iKrhgVVQFS19h+dsJ18nUieTo9nUr/yKDKs1DhnNfaouyOvg16Vz5yC1vG1ZRpzRcFmfKi8HRGThHIdfLSY= Received: by 10.114.175.16 with SMTP id x16mr2470696wae.116.1210203002594; Wed, 07 May 2008 16:30:02 -0700 (PDT) Received: by 10.115.72.8 with HTTP; Wed, 7 May 2008 16:30:02 -0700 (PDT) Message-ID: <353f2c6f0805071630i5957d519qee72e64addcc1adb@mail.gmail.com> Date: Thu, 8 May 2008 01:30:02 +0200 To: "PHP Internals" MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline Subject: Re: Class Properties in Interfaces? From: lew21st@gmail.com (LEW21) Hi, On May 7, 2008, at 2:12 AM, Jeff Moore wrote: > Specifying the accessor methods in an interface reveals too much of > the implementation. Properties (the kind with accessor methods) are > themselves an abstract concept. You want to be able to take an > interface definition such as: > > interface foo { > public $bar; // if you prefer this to abstract $foo; > } > > and implement it like this: > > class DoIt implements foo { > public $bar; > } > > or to implement it using setters, using your notation: > > class DoIt2 implements foo { > public $foo { > public function get(); > protected function set($value); > } > } > > The whole point of this kind of property is that the caller is never > supposed to know if they are just accessing a object instance variable > or an accessor method. This is called the uniform access principle. > http://en.wikipedia.org/wiki/Uniform_access_principle I like this concept, so I extended it and wrote some code ("SimplePDO") showing my ideas. You can see it here: http://internals.php.pastebin.com/f6a3cc2f This way, every property can have 0 - 6 functions, that change methods of accessing it: void load() // (made for simple lazy-loading) typeof(property) get() void validate(mixed $value) throws InvalidValueException typeof(property) set(typeof(property) $value) bool isset() void unset() They are called in this way: PHP code: echo $object->property; What PHP does behind the scenes (in PHP-based pseudocode, somebody will have to write it in C for Zend Engine): $object = $object; $property = 'property'; if (!property_is_readable($object->$property)) { throw new PropertyNotReadableException($object, $property) } if (is_null($object->$property.realValue)) { try { $object->$property.load(); } catch (UndefinedPropertyMethodException $e) {} } try { return $object->$property.get(); } catch (UndefinedPropertyMethodException $e) { return $object->$property.realValue; } PHP code: $object->property = 'new value'; What PHP does behind the scenes: $object = $object; $property = 'property'; $newValue = 'new value'; if (!property_is_writable($object->$property)) { throw new PropertyNotWritableException($object, $property) } try { $object->$property.validate($newValue); } catch (UndefinedPropertyMethodException $e) {} /* Does not catch InvalidValueException */ try { return $object->$property.set($newValue); } catch (UndefinedPropertyMethodException $e) { return $object->$property.realValue = $newValue; } PHP code: isset($object->property); What PHP does behind the scenes: $object = $object; $property = 'property'; if (!property_is_readable($object->$property)) { return false; } try { return $object->$property.isset(); } catch (UndefinedPropertyMethodException $e) { return (is_null($object->$property.realValue)) ? false : true; } PHP code: unset($object->property); What PHP does behind the scenes: $object = $object; $property = 'property'; if (!property_is_writable($object->$property)) { throw new PropertyNotWritableException($object, $property) } try { $object->$property.unset(); } catch (UndefinedPropertyMethodException $e) { try { $object->$property.set(null); } catch (UndefinedPropertyMethodException $e) { $object->$property.realValue = null; } } property_is_readable() and property_is_writable() language constructs check if property is readable/writable in current context.