FAQ
Hello,

This is my first time using a mailing list, so please bear with me.

Some time back I suggested that PHP should have a property get/set syntax
similar to that of Microsoft's C# language. One of the PHP developers
suggested that if I were serious about it, I should write an RFC. I have
done just that, and I would now like to present my RFC to everyone here in
internals, in order to start a discussion on the topic.

The RFC:

Many modern languages have a special syntax for writing get/set method
pairs. All that PHP currently supports is __get and __set, which while
great for writing generic get/set methods is nearly useless when it comes
to individual properties. Our only other choice is the age old process of
writing custom class methods to make our get/set methods. Not only does
this lack any kind of uniformity, but it also complicates the syntax
($foo->getBar() and $foo->setBar('baz') instead of $foo->bar and
$foo->bar='baz'). I believe that if PHP is going embrace modern
object-oriented design, including encapsulation, than it needs a modern
solution to property getters and setters.

I wont add much more here, but rather let the RFC itself do the talking.
It is fairly well fleshed out, and should explain everything clearly
enough.

Link to the RFC:
http://wiki.php.net/rfc/propertygetsetsyntax

Thanks,
Dennis Robinson

Search Discussions

  • Larry Garfield at Nov 29, 2010 at 12:14 am

    On Sunday, November 28, 2010 5:18:40 pm president@basnetworks.net wrote:

    Link to the RFC:
    http://wiki.php.net/rfc/propertygetsetsyntax

    Thanks,
    Dennis Robinson
    This is a very well-written and well-thought through RFC, Dennis. Nicely
    done.

    That said, I am not yet convinced. :-)

    First of all, I have generally found the Bean-style getter/setter approach to
    be a sign of poor encapsulation to begin with. You shouldn't be mucking with
    internal elements of an object in the first place, period. More details on
    that here:

    http://www.garfieldtech.com/blog/property-visibility

    However, I do see a potential use here if "properties" are treated
    conceptually as an entirely new concept and not as an indirection layer for
    class properties. That would make them more akin to a class that has both
    methods and also implements ArrayAccess for "properties of the conceptual
    object, that may not have anything to do with internal class members."

    Viewed from that angle, I would have the following comments:

    - I strongly prefer the first syntax over the second. The "property" keyword
    improves readability, and the closing semi-colon is going to be forgotten on a
    daily basis. I still forget sometimes when to use it and when not to when
    writing Javascript. :-) I cannot speak to the engine complexity involved but
    from a PHP-autor point of view I believe the first syntax is much easier to
    use.

    - The use of identical syntax for class members and properties could create
    confusion as to which is which. One could argue that is the point, but only
    if we view properties as "just" an indirection layer around the physical class
    members, which as I noted above I believe is a poor architectural design.
    There may not be an alternative here, but I mention it for completeness.

    - I concur with the RFP's preference for "implicit write-only" properties
    rather than explicit, as it seems more flexible.

    - The layering of accessibility keywords I find intriguing, in a mostly good
    way. That can offer a great deal of flexibility to control who can do what
    when. However, I am concerned about the confusion possible in the following:

    public property Hours {
    get { return $this->seconds / 3600; }
    protected set { $this->seconds = $value * 3600; }
    }

    The set method is then scoped with two different visibility directives: public
    and protected. Which applies? Since both are optional (presumably) I can see
    a potential here for confusion, especially if you also start mentioning
    keywords like final. This should be made more definitive if possible.

    - If interfaces can declare properties (niiice), Traits should be able to
    provide them. That provides full parallelism with methods, which I believe
    developers will expect.

    - I am curious what the performance implication would be. For instance, I've
    benchmarked both magic property access (__get()) and ArrayAccess to be around
    4 times as slow as accessing a class member.

    http://www.garfieldtech.com/blog/benchmarking-magic

    Since in essence what is happening here is binding a function to fire when a
    class member is accessed (given the identical syntax), I'm concerned that
    there would be a similar performance issue. A 4x slower performance cost
    would make me avoid properties in favor of class members unless I absolutely
    needed them. A 2x or less I could see making more use of.

    - Which also brings up an interesting question:

    class Foo {
    public $a = 1;
    protected $b = 2;

    public property $a { get { return 3; } }
    public property $b { get { return 4; } }
    }

    $f = new Foo();
    print $f->a . PHP_EOL; // Does this print 1 or 3?
    print $f->b . PHP_EOL; // Does this print 2 or 4, or error?

    I'm sure there's arguments every which way. My preference would be for
    properties to always win over class members, followed by the above code sample
    being a compile error.

    It gets even tricker when you introduce inheritance. If a child class has a
    [property|class member] of the same name as a parent's [class member|
    property], then what?

    That's all I got for now. Once again, nice RFP but still needs some thinking.

    --Larry Garfield
  • Pierre Joye at Nov 29, 2010 at 12:22 am
    hi,

    Great job, very well written proposal.

    Quick notice: the readonly keyword work without being used with a
    method (or the default getter/setter):

    class A {
    public readonly propro;
    }

    The writeonly property (useful from time to time) is not supported by
    default but using the custom definitions.

    I'm all in favour of having that in PHP. However not in an immediate
    future (ie 5.4) but the next major version.

    Cheers,
    On Mon, Nov 29, 2010 at 12:18 AM, wrote:
    Hello,

    This is my first time using a mailing list, so please bear with me.

    Some time back I suggested that PHP should have a property get/set syntax
    similar to that of Microsoft's C# language.  One of the PHP developers
    suggested that if I were serious about it, I should write an RFC.  I have
    done just that, and I would now like to present my RFC to everyone here in
    internals, in order to start a discussion on the topic.

    The RFC:

    Many modern languages have a special syntax for writing get/set method
    pairs.  All that PHP currently supports is __get and __set, which while
    great for writing generic get/set methods is nearly useless when it comes
    to individual properties.  Our only other choice is the age old process of
    writing custom class methods to make our get/set methods.  Not only does
    this lack any kind of uniformity, but it also complicates the syntax
    ($foo->getBar() and $foo->setBar('baz') instead of $foo->bar and
    $foo->bar='baz').  I believe that if PHP is going embrace modern
    object-oriented design, including encapsulation, than it needs a modern
    solution to property getters and setters.

    I wont add much more here, but rather let the RFC itself do the talking.
    It is fairly well fleshed out, and should explain everything clearly
    enough.

    Link to the RFC:
    http://wiki.php.net/rfc/propertygetsetsyntax

    Thanks,
    Dennis Robinson


    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php


    --
    Pierre

    @pierrejoye | http://blog.thepimp.net | http://www.libgd.org
  • Christian Kaps at Nov 29, 2010 at 7:48 am
    Hi,

    I like the idea of the property get/set syntax, but in my opinion it
    doesn't figure with PHP's syntax, because it breaks the readability. The
    problem for me is the nesting of the inner set and get. How do you
    document these syntax.

    /**
    *
    */
    public $name {

    /**
    *
    */
    get {
    return $this->name;
    }

    /**
    *
    */
    set {
    $this->name = htmlentities($value);
    $this->name = strip_tags($this->name);
    }
    };


    What I also miss is the lack of type hinting. As I see it, it isn't
    possible with this syntax.

    I would prefer the syntax from ActionScript. This is more like the
    normal PHP function syntax with an additional set or get keyword.

    /**
    *
    */
    public function set name(string $name) {
    $this->name = htmlentities($name);
    $this->name = strip_tags($this->name);
    }

    /**
    *
    */
    public function get name($name) {
    return $this->name;
    }

    Greetings,
    Christian
    On Sun, 28 Nov 2010 18:18:40 -0500, president@basnetworks.net wrote:
    Hello,

    This is my first time using a mailing list, so please bear with me.

    Some time back I suggested that PHP should have a property get/set
    syntax
    similar to that of Microsoft's C# language. One of the PHP
    developers
    suggested that if I were serious about it, I should write an RFC. I
    have
    done just that, and I would now like to present my RFC to everyone
    here in
    internals, in order to start a discussion on the topic.

    The RFC:

    Many modern languages have a special syntax for writing get/set
    method
    pairs. All that PHP currently supports is __get and __set, which
    while
    great for writing generic get/set methods is nearly useless when it
    comes
    to individual properties. Our only other choice is the age old
    process of
    writing custom class methods to make our get/set methods. Not only
    does
    this lack any kind of uniformity, but it also complicates the syntax
    ($foo->getBar() and $foo->setBar('baz') instead of $foo->bar and
    $foo->bar='baz'). I believe that if PHP is going embrace modern
    object-oriented design, including encapsulation, than it needs a
    modern
    solution to property getters and setters.

    I wont add much more here, but rather let the RFC itself do the
    talking.
    It is fairly well fleshed out, and should explain everything clearly
    enough.

    Link to the RFC:
    http://wiki.php.net/rfc/propertygetsetsyntax

    Thanks,
    Dennis Robinson
  • Chad Fulton at Nov 29, 2010 at 8:36 am

    On Sun, Nov 28, 2010 at 11:48 PM, Christian Kaps wrote:
    ...
    /**
    *
    */
    public function set name(string $name) {
    $this->name = htmlentities($name);
    $this->name = strip_tags($this->name);
    }

    /**
    *
    */
    public function get name($name) {
    return $this->name;
    }

    Greetings,
    Christian
    For whatever it's worth, I think that this syntax fits much better
    into PHP than do either of the those in the RFC.
  • Richard Quadling at Nov 29, 2010 at 10:54 am

    On 28 November 2010 23:18, wrote:
    Link to the RFC:
    http://wiki.php.net/rfc/propertygetsetsyntax

    Thanks,
    Dennis Robinson
    I'd really like this feature to be part of PHP.

    I don't particularly like the use of what looks like a closure for the set/get.

    I used to code in Delphi and I always like the way in which their
    properties were defined.

    Essentially, the setter and getter are normal methods which are cherry
    picked for a property [1].

    <?php
    class TimePeriod
    {
    protected $seconds;

    public property Hours read getHours write setHours;

    protected function getHours()
    {
    return $this->seconds / 3600;
    }

    protected function setHours()
    {
    $this->seconds = $value * 3600;
    }

    // This property is read-only
    public property Minutes read getMinutes;

    protected function getMinutes()
    {
    return $this->seconds / 60;
    }

    public property Milliseconds read getMilliseconds write setMilliseconds;

    public function getMilliseconds()
    {
    // This method is public
    return $this->seconds * 60;
    }

    protected function setMilliseconds()
    {
    // This method is protected
    $this->seconds = $value * 3600;
    }
    }

    For me, the advantage here is that I can independently the methods
    from the property. If I want to force a subclass to implement a
    setter/getter, then I can abstract the function in the base class.
    Sure, some may say that I should be using an interface. I disagree as
    I probably don't want the methods to be public. Protected or even
    private and/or final.

    The classic example is one of shapes. Every shape has a public $area
    property, but the value would be provided by an abstract protected
    TShape::getArea(); method. I can also finalise them, so, for example,
    a triangle shape could have a final protected getArea() method and all
    sub classes of triangles (scalene, isosceles, equilateral) would not
    implement their own getArea() method.

    The downside is certainly that the code is more verbose than I would
    guess many people would like.

    Regards,

    Richard.

    [1] http://www.delphibasics.co.uk/RTL.asp?Name=Property
    --
    Richard Quadling
    Twitter : EE : Zend
    @RQuadling : e-e.com/M_248814.html : bit.ly/9O8vFY
  • Ángel González at Nov 29, 2010 at 2:30 pm

    Richard Quadling wrote:
    I'd really like this feature to be part of PHP.

    I don't particularly like the use of what looks like a closure for the set/get.

    I used to code in Delphi and I always like the way in which their
    properties were defined.

    Essentially, the setter and getter are normal methods which are cherry
    picked for a property [1].

    <?php
    class TimePeriod
    {
    protected $seconds;

    public property Hours read getHours write setHours;

    protected function getHours()
    {
    return $this->seconds / 3600;
    }

    protected function setHours()
    {
    $this->seconds = $value * 3600;
    }

    // This property is read-only
    public property Minutes read getMinutes;

    protected function getMinutes()
    {
    return $this->seconds / 60;
    }

    public property Milliseconds read getMilliseconds write setMilliseconds;

    public function getMilliseconds()
    {
    // This method is public
    return $this->seconds * 60;
    }

    protected function setMilliseconds()
    {
    // This method is protected
    $this->seconds = $value * 3600;
    }
    }

    For me, the advantage here is that I can independently the methods
    from the property. If I want to force a subclass to implement a
    setter/getter, then I can abstract the function in the base class.
    Sure, some may say that I should be using an interface. I disagree as
    I probably don't want the methods to be public. Protected or even
    private and/or final.

    The classic example is one of shapes. Every shape has a public $area
    property, but the value would be provided by an abstract protected
    TShape::getArea(); method. I can also finalise them, so, for example,
    a triangle shape could have a final protected getArea() method and all
    sub classes of triangles (scalene, isosceles, equilateral) would not
    implement their own getArea() method.

    The downside is certainly that the code is more verbose than I would
    guess many people would like.

    Regards,

    Richard.

    [1] http://www.delphibasics.co.uk/RTL.asp?Name=Property
    setMilliseconds() should have $value as parameter instead of a magic name.

    What about allowing this syntax to attach the property to a variable?

    For instance:

    <?php
    class TimePeriod
    {
    protected $seconds;
    protected $minutes;
    protected $hours;

    public property Seconds read $seconds write setSeconds;
    public property Minutes read $seconds write setMinutes;
    public property Hours read $seconds write setHours;

    public function setSeconds($seconds)
    {
    if ($seconds >= 0 && $seconds < 60) $this->seconds = $seconds;
    }

    public function setMinutes($minutes)
    {
    if ($minutes >= 0 && $minutes < 60) $this->minutes = $minutes;
    }

    public function setHours($hours)
    {
    if ($hours >= 0 && $hours < 24) $this->hours = $hours;
    }

    }

    We only want to perform checks on write, so instead of writing the trivial
    getters, the property is set to the variable itself. Child classes could
    reattach it to a function if needing more control.
  • Richard Quadling at Nov 29, 2010 at 4:10 pm

    2010/11/29 Ángel González <keisial@gmail.com>:
    Richard Quadling wrote:
    setMilliseconds() should have $value as parameter instead of a magic name.

    What about allowing this syntax to attach the property to a variable?

    For instance:

    <?php
    class TimePeriod
    {
    protected $seconds;
    protected $minutes;
    protected $hours;

    public property Seconds read $seconds write setSeconds;
    public property Minutes read $seconds write setMinutes;
    public property Hours read $seconds write setHours;

    public function setSeconds($seconds)
    {
    if ($seconds >= 0 && $seconds < 60) $this->seconds = $seconds;
    }

    public function setMinutes($minutes)
    {
    if ($minutes >= 0 && $minutes < 60) $this->minutes = $minutes;
    }

    public function setHours($hours)
    {
    if ($hours >= 0 && $hours < 24) $this->hours = $hours;
    }

    }

    We only want to perform checks on write, so instead of writing the trivial
    getters, the property is set to the variable itself. Child classes could
    reattach it to a function if needing more control.
    Ouch. I messed up on the example code. Completely forget that there
    was a parameter to process...

    As for reading $seconds directly ...

    Well.

    If you think of the element that follows read as $this->xxxx, then if
    the parser can handle both ...

    read $seconds
    read getSeconds

    then yes for both.

    If not, then I'd guess that the getSeconds version should be the one
    we use as the value may not actually exist without some processing.

    Richard.

    --
    Richard Quadling
    Twitter : EE : Zend
    @RQuadling : e-e.com/M_248814.html : bit.ly/9O8vFY
  • Ángel González at Nov 29, 2010 at 8:42 pm

    Richard Quadling wrote:
    As for reading $seconds directly ...

    Well.

    If you think of the element that follows read as $this->xxxx, then if
    the parser can handle both ...

    read $seconds
    read getSeconds

    then yes for both.

    If not, then I'd guess that the getSeconds version should be the one
    we use as the value may not actually exist without some processing.

    Richard.
    If it begins with $, it's a variable name, so map to that class member
    variable. If it is instead a plain T_STRING, take that as a member call.

    I'm not sure to be understanding the issue you're mentioning.
  • Richard Quadling at Nov 30, 2010 at 2:07 pm

    2010/11/29 Ángel González <keisial@gmail.com>:
    Richard Quadling wrote:
    As for reading $seconds directly ...

    Well.

    If you think of the element that follows read as $this->xxxx, then if
    the parser can handle both ...

    read $seconds
    read getSeconds

    then yes for both.

    If not, then I'd guess that the getSeconds version should be the one
    we use as the value may not actually exist without some processing.

    Richard.
    If it begins with $, it's a variable name, so map to that class member
    variable. If it is instead a plain T_STRING, take that as a member call.

    I'm not sure to be understanding the issue you're mentioning.
    If the proposal incorporated support for getting the value from a
    local-scoped variable (I assume the variable has to be part of the
    current class or one of its parents?) as well as calling the getter,
    then that really does seem to allow everyone everything they need.


    --
    Richard Quadling
    Twitter : EE : Zend
    @RQuadling : e-e.com/M_248814.html : bit.ly/9O8vFY
  • Ángel González at Nov 30, 2010 at 11:20 pm

    Richard Quadling wrote:
    (I assume the variable has to be part of the current class or one of its parents?)
    Yes. I don't think it makes sense to have a class property actually read
    a global.
    If a project really need it (eg. some migration from procedural style to
    classes), then
    use the verbose syntax.
  • Benjamin Dubois at Nov 29, 2010 at 8:48 pm
    Hi !

    This is my first email here (I'm just a PHP user, with only very basic C skills, but I'm working on it), and I would love to contribute to this project.

    I have been working with Objective-c lately, and it has a very flexible and short way to deal with properties, which could look like this in PHP :

    <?php
    class TimePeriod {
    protected $seconds;
    protected $minutes;
    protected $hours;


    @synthesize (readwrite) $hours, $minutes;
    @synthesize (readonly) $seconds;
    }

    NB : I intentionally skipped the @property declaration wich I believe is a specific need for objc (used to allow dot syntax usage).


    In objc, this notation allows to :

    - use dot syntax for accessing properties (using their getters/setters only, all properties are protected in objc)
    - write your own getters/setters (only the missing ones are generated)


    In Php, the pros of this syntax would be :

    - very concise
    - no interference with existing code (except certain conditions)
    - allows to override generated getters and setters with custom code
    - may work with the existing code base

    The cons :

    - new syntax to learn (even if it is quite simple)
    - need to use pre-determined setters and getters names to keep simplicity, which could potentially lead to BC break in some (hopefully rare) cases.


    What do you think about it ?


    Regards,

    Benjamin




    Le 29 nov. 2010 à 17:10, Richard Quadling a écrit :
    2010/11/29 Ángel González <keisial@gmail.com>:
    Richard Quadling wrote:
    setMilliseconds() should have $value as parameter instead of a magic name.

    What about allowing this syntax to attach the property to a variable?

    For instance:

    <?php
    class TimePeriod
    {
    protected $seconds;
    protected $minutes;
    protected $hours;

    public property Seconds read $seconds write setSeconds;
    public property Minutes read $seconds write setMinutes;
    public property Hours read $seconds write setHours;

    public function setSeconds($seconds)
    {
    if ($seconds >= 0 && $seconds < 60) $this->seconds = $seconds;
    }

    public function setMinutes($minutes)
    {
    if ($minutes >= 0 && $minutes < 60) $this->minutes = $minutes;
    }

    public function setHours($hours)
    {
    if ($hours >= 0 && $hours < 24) $this->hours = $hours;
    }

    }

    We only want to perform checks on write, so instead of writing the trivial
    getters, the property is set to the variable itself. Child classes could
    reattach it to a function if needing more control.
    Ouch. I messed up on the example code. Completely forget that there
    was a parameter to process...

    As for reading $seconds directly ...

    Well.

    If you think of the element that follows read as $this->xxxx, then if
    the parser can handle both ...

    read $seconds
    read getSeconds

    then yes for both.

    If not, then I'd guess that the getSeconds version should be the one
    we use as the value may not actually exist without some processing.

    Richard.

    --
    Richard Quadling
    Twitter : EE : Zend
    @RQuadling : e-e.com/M_248814.html : bit.ly/9O8vFY

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
  • Larry at Nov 29, 2010 at 6:18 pm

    On 11/29/10 8:30 AM, Ángel González wrote:

    What about allowing this syntax to attach the property to a variable?

    For instance:

    <?php
    class TimePeriod
    {
    protected $seconds;
    protected $minutes;
    protected $hours;

    public property Seconds read $seconds write setSeconds;
    public property Minutes read $seconds write setMinutes;
    public property Hours read $seconds write setHours;

    public function setSeconds($seconds)
    {
    if ($seconds>= 0&& $seconds< 60) $this->seconds = $seconds;
    }

    public function setMinutes($minutes)
    {
    if ($minutes>= 0&& $minutes< 60) $this->minutes = $minutes;
    }

    public function setHours($hours)
    {
    if ($hours>= 0&& $hours< 24) $this->hours = $hours;
    }

    }

    We only want to perform checks on write, so instead of writing the trivial
    getters, the property is set to the variable itself. Child classes could
    reattach it to a function if needing more control.
    Another advantage here would presumably be performance. If there's no
    getter defined then the engine could simply map $foo->bar to the class
    member directly (which is really fast) and not to a method, so there's
    no added overhead there. That still leaves the question of what happens
    with name collisions, though.

    ... and that makes me think that someone is sure to ask about runtime
    changes to the property structure sooner or later, as we keep asking
    about methods (and *sort of* have figured out with binding closures to
    objects, if that did actually get committed), so I'll go ahead and ask
    it now. :-)

    --Larry Garfield
  • Johannes Schlüter at Nov 29, 2010 at 6:42 pm

    On Mon, 2010-11-29 at 12:18 -0600, larry@garfieldtech.com wrote:
    Another advantage here would presumably be performance. If there's
    no
    getter defined then the engine could simply map $foo->bar to the
    class
    member directly (which is really fast) and not to a method, so
    there's
    no added overhead there. That still leaves the question of what
    happens
    with name collisions, though.
    Don't kow what you mean by "the engine" in this case? The compiler? - no
    the compiler can't a) it has no idea what type $foo is b) think about
    inheritance etc. The executor - well there's no win possible.

    johannes
  • Larry at Nov 29, 2010 at 7:40 pm

    On 11/29/10 12:41 PM, Johannes Schlüter wrote:
    On Mon, 2010-11-29 at 12:18 -0600, larry@garfieldtech.com wrote:
    Another advantage here would presumably be performance. If there's
    no
    getter defined then the engine could simply map $foo->bar to the
    class
    member directly (which is really fast) and not to a method, so
    there's
    no added overhead there. That still leaves the question of what
    happens
    with name collisions, though.
    Don't kow what you mean by "the engine" in this case? The compiler? - no
    the compiler can't a) it has no idea what type $foo is b) think about
    inheritance etc. The executor - well there's no win possible.

    johannes
    I was referring to the compiler I guess. I don't do C so I have no idea
    what it's capable of. If that's not a possible performance optimization
    point, then blargh.

    I still want to keep the performance implications in mind, as this
    sounds like something that we'd want to use a lot but could also cost a
    lot more than it seems at first glance if we're not careful.

    --Larry Garfield
  • Johannes Schlüter at Nov 29, 2010 at 7:57 pm

    On Mon, 2010-11-29 at 13:40 -0600, larry@garfieldtech.com wrote:
    I still want to keep the performance implications in mind, as this
    sounds like something that we'd want to use a lot but could also cost a
    lot more than it seems at first glance if we're not careful.
    By making properties in memory a little bigger one might write the
    accessors in the same table as the actual properties one might possibly
    reduce the CPU requirement abit. While one has to touch most places
    dealing with properties internally (while that's probably needed
    anyways). But well, unless there is an implementation all performance
    ideas are guesses ... educated guesses at best.

    johannes
  • Matthew Weier O'Phinney at Nov 29, 2010 at 2:55 pm

    On 2010-11-29, Richard Quadling wrote:
    On 28 November 2010 23:18, wrote:
    Link to the RFC:
    http://wiki.php.net/rfc/propertygetsetsyntax

    Thanks,
    Dennis Robinson
    I'd really like this feature to be part of PHP.

    I don't particularly like the use of what looks like a closure for the set/get.

    I used to code in Delphi and I always like the way in which their
    properties were defined.

    Essentially, the setter and getter are normal methods which are cherry
    picked for a property [1].

    <?php
    class TimePeriod
    {
    protected $seconds;

    public property Hours read getHours write setHours;

    protected function getHours()
    {
    return $this->seconds / 3600;
    }

    protected function setHours()
    {
    $this->seconds = $value * 3600;
    } <snip>
    For me, the advantage here is that I can independently the methods
    from the property. If I want to force a subclass to implement a
    setter/getter, then I can abstract the function in the base class.
    I prefer this as well. It often aids readability to use fluent
    interfaces when performing operations that are simply changing state,
    and being able to call the setters directly would make that possible:

    $time->setHours(3)
    ->setMinutes(17)
    ->setSeconds(34);

    Additionally, this seems like a very natural fit with traits, making it
    possible to really succinctly define behavior to mix in with classes.

    --
    Matthew Weier O'Phinney
    Project Lead | matthew@zend.com
    Zend Framework | http://framework.zend.com/
    PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc
  • Stas Malyshev at Nov 29, 2010 at 3:08 pm
    Hi!
    public property Hours read getHours write setHours;
    I actually like that, though I think we should support the whole
    existing semantics, i.e. get/set/isset/unset. And probably keep the
    names, so we don't call the same thing both "read" and "get".

    Having them called __get etc. would even remove the need for another
    keyword, probably, but this looks ugly :(
    --
    Stanislav Malyshev, Software Architect
    SugarCRM: http://www.sugarcrm.com/
    (408)454-6900 ext. 227
  • President at Nov 30, 2010 at 12:48 pm
    Hi Richard,


    I'd really like this feature to be part of PHP.

    I don't particularly like the use of what looks like a closure for the
    set/get.
    While it looks like a closure, it may not necessarily be one. What I have
    presented in my RFC is a syntax, but I make little assumption about how it
    would be implemented, as that would be out stepping my expertise.

    In C#, when a property gets compiled it is actually turned into two normal
    class methods in a special namespace. Looking at a compiled C# library
    with reflector will reveal this underlying implementation. So when a call
    to a property is compiled in C#, it is simple replaced with a call to a
    method. The properties themselves are nothing more than syntactic sugar.

    Since PHP is interpreted instead of compiled, this may not be an ideal
    solution, but I couldn't guess as to what would be a better method.
    Preferably something that re-uses the existing class method
    interpretation.

    I used to code in Delphi and I always like the way in which their
    properties were defined.

    Essentially, the setter and getter are normal methods which are cherry
    picked for a property [1].

    <?php
    class TimePeriod
    {
    protected $seconds;

    public property Hours read getHours write setHours;

    protected function getHours()
    {
    return $this->seconds / 3600;
    }

    protected function setHours()
    {
    $this->seconds = $value * 3600;
    }

    // This property is read-only
    public property Minutes read getMinutes;

    protected function getMinutes()
    {
    return $this->seconds / 60;
    }

    public property Milliseconds read getMilliseconds write
    setMilliseconds;

    public function getMilliseconds()
    {
    // This method is public
    return $this->seconds * 60;
    }

    protected function setMilliseconds()
    {
    // This method is protected
    $this->seconds = $value * 3600;
    }
    }

    For me, the advantage here is that I can independently the methods
    from the property. If I want to force a subclass to implement a
    setter/getter, then I can abstract the function in the base class.
    Sure, some may say that I should be using an interface. I disagree as
    I probably don't want the methods to be public. Protected or even
    private and/or final.
    In the syntax I provided in my RFC, it is certainly possible to define a
    property with only a get or only a set method (these are implicit
    read-only and write-only properties). Furthermore, it is also possible to
    set the visibility of the get and set methods individually, as well as
    making either one final, static or (and I forgot to mention this in the
    RFC) abstract. But the advantage of my syntax, is not only can these
    things be set individually, but they can also be set just once for the
    pair, by specifying them on the property itself. This makes for cleaner
    and more readable code.

    My syntax also gives several other advantages over the delphi syntax. It
    is more logical, as it makes the property look more like a class variable
    than a class method. This makes sense because you call it like a
    variable. Additionally, because the get/set methods need to be contained
    within the body of the property definition, you immediately know if a
    property has both a get and a set method at a quick glance - you do not
    have to hunt through the class to see if there is another definition
    somewhere else.

    The classic example is one of shapes. Every shape has a public $area
    property, but the value would be provided by an abstract protected
    TShape::getArea(); method. I can also finalise them, so, for example,
    a triangle shape could have a final protected getArea() method and all
    sub classes of triangles (scalene, isosceles, equilateral) would not
    implement their own getArea() method.
    This is possible with the syntax I provided. I would suggest reading more
    about the C# syntax, which my suggested syntax is based off of, as it will
    explain all of your questions.

    http://msdn.microsoft.com/en-us/library/x9fsa0sw%28VS.80%29.aspx

    - Dennis
  • Richard Quadling at Nov 30, 2010 at 3:01 pm

    On 30 November 2010 12:48, wrote:
    Hi Richard,


    I'd really like this feature to be part of PHP.

    I don't particularly like the use of what looks like a closure for the
    set/get.
    While it looks like a closure, it may not necessarily be one.  What I have
    presented in my RFC is a syntax, but I make little assumption about how it
    would be implemented, as that would be out stepping my expertise.

    In C#, when a property gets compiled it is actually turned into two normal
    class methods in a special namespace.  Looking at a compiled C# library
    with reflector will reveal this underlying implementation.  So when a call
    to a property is compiled in C#, it is simple replaced with a call to a
    method.  The properties themselves are nothing more than syntactic sugar.

    Since PHP is interpreted instead of compiled, this may not be an ideal
    solution, but I couldn't guess as to what would be a better method.
    Preferably something that re-uses the existing class method
    interpretation.

    I used to code in Delphi and I always like the way in which their
    properties were defined.

    Essentially, the setter and getter are normal methods which are cherry
    picked for a property [1].

    <?php
    class TimePeriod
    {
    protected $seconds;

    public property Hours read getHours write setHours;

    protected function getHours()
    {
    return $this->seconds / 3600;
    }

    protected function setHours()
    {
    $this->seconds = $value * 3600;
    }

    // This property is read-only
    public property Minutes read getMinutes;

    protected function getMinutes()
    {
    return $this->seconds / 60;
    }

    public property Milliseconds read getMilliseconds write
    setMilliseconds;

    public function getMilliseconds()
    {
    // This method is public
    return $this->seconds * 60;
    }

    protected function setMilliseconds()
    {
    // This method is protected
    $this->seconds = $value * 3600;
    }
    }

    For me, the advantage here is that I can independently the methods
    from the property. If I want to force a subclass to implement a
    setter/getter, then I can abstract the function in the base class.
    Sure, some may say that I should be using an interface. I disagree as
    I probably don't want the methods to be public. Protected or even
    private and/or final.
    In the syntax I provided in my RFC, it is certainly possible to define a
    property with only a get or only a set method (these are implicit
    read-only and write-only properties).  Furthermore, it is also possible to
    set the visibility of the get and set methods individually, as well as
    making either one final, static or (and I forgot to mention this in the
    RFC) abstract.  But the advantage of my syntax, is not only can these
    things be set individually, but they can also be set just once for the
    pair, by specifying them on the property itself.  This makes for cleaner
    and more readable code.

    My syntax also gives several other advantages over the delphi syntax.  It
    is more logical, as it makes the property look more like a class variable
    than a class method.  This makes sense because you call it like a
    variable.  Additionally, because the get/set methods need to be contained
    within the body of the property definition, you immediately know if a
    property has both a get and a set method at a quick glance - you do not
    have to hunt through the class to see if there is another definition
    somewhere else.

    The classic example is one of shapes. Every shape has a public $area
    property, but the value would be provided by an abstract protected
    TShape::getArea(); method. I can also finalise them, so, for example,
    a triangle shape could have a final protected getArea() method and all
    sub classes of triangles (scalene, isosceles, equilateral) would not
    implement their own getArea() method.
    This is possible with the syntax I provided.  I would suggest reading more
    about the C# syntax, which my suggested syntax is based off of, as it will
    explain all of your questions.

    http://msdn.microsoft.com/en-us/library/x9fsa0sw%28VS.80%29.aspx

    - Dennis
    Thanks for your reply.


    Fundamentally, a big +1 from my little voice on having setters/getters in PHP.


    The issue of documentation is probably that the documentation tools
    would have to adapt. As things stand PHPDoc doesn't support
    namespaces, so setters/getters would just be added to the WIBNI list.


    With regard to the value supplied to the set method, would it make
    more sense for PHP to be ...

    set($value) { $this->seconds = $value * 3600; }

    or

    set { $this->seconds = __SETVALUE__ * 3600; }

    Having $value without a clear indication of where it comes from
    doesn't read quite right.

    $value is way to generic to be magically created. __SETVALUE__ (or
    __SOMETHINGELSE__) is clear in this regard.




    Richard.

    --
    Richard Quadling
    Twitter : EE : Zend
    @RQuadling : e-e.com/M_248814.html : bit.ly/9O8vFY
  • President at Dec 1, 2010 at 12:39 am

    Thanks for your reply.

    Fundamentally, a big +1 from my little voice on having setters/getters in
    PHP.


    The issue of documentation is probably that the documentation tools
    would have to adapt. As things stand PHPDoc doesn't support
    namespaces, so setters/getters would just be added to the WIBNI list.
    Here is a reply I wrote to Christan Kaps on the same subject:
    Christan Wrote:

    I like the idea of the property get/set syntax, but in my opinion it
    doesn't figure with PHP's syntax, because it breaks the readability. The
    problem for me is the nesting of the inner set and get. How do you
    document these syntax.

    /**
    *
    */
    public $name {

    /**
    *
    */
    get {
    return $this->name;
    }

    /**
    *
    */
    set {
    $this->name = htmlentities($value);
    $this->name = strip_tags($this->name);
    }
    };
    Typically you only document the property as a whole, and not the
    individual get and set method. Since they are a pair, there should be no
    reason to document them separately. If the get method is doing something
    totally different from the set, then they should not be paired, as that is
    confusing.

    In C# you would typically see documentation like this:

    Only a get method:
    /// <summary>Gets the duration of the Timespan in seconds.</summary>
    public int Seconds { get; }

    Only a set method:
    /// <summary>Sets the duration of the Timespan in seconds.</summary>
    public int Seconds { set; }

    Both a get and set method:
    /// <summary>Gets/sets the duration of the Timespan in seconds.</summary>
    public int Seconds { get; set; }




    With regard to the value supplied to the set method, would it make
    more sense for PHP to be ...

    set($value) { $this->seconds = $value * 3600; }

    or

    set { $this->seconds = __SETVALUE__ * 3600; }

    Having $value without a clear indication of where it comes from
    doesn't read quite right.

    $value is way to generic to be magically created. __SETVALUE__ (or
    __SOMETHINGELSE__) is clear in this regard.
    That is a good point. In C# it is simple the variable "value", which is
    where I got $value from. Rather magicy, yes. A constant could work, and
    would be more in line with PHP's magic constants. Just a quick question
    though, can a constant store all of the same data variable can? What
    about a reference?

    Also, sometimes users in C# like to modify the contents of the "value"
    variable before using it for something else. If it were a constant this
    would not be possible, you would have to define a new variable, then copy
    the value from the constant, which seems unnecessarily cumbersome.

    - Dennis
  • Jonathan Bond-Caron at Nov 29, 2010 at 2:23 pm

    On Sun Nov 28 06:18 PM, president@basnetworks.net wrote:

    Link to the RFC:
    http://wiki.php.net/rfc/propertygetsetsyntax
    Nice RFC, just an idea for an alternative syntax (added to the RFC as #2):

    property Hours {
    get { return $this->seconds / 3600; }
    set { $this->seconds = $value * 3600; } // The variable $value holds
    the incoming value to be "set"
    }

    class TimePeriod
    {
    private $seconds;

    public [Hours] $hours1;
    public {use Hours;} $hours2;
    }

    Would favor re-use similar to traits by injecting the set/get code around
    the property.
  • Stas Malyshev at Nov 29, 2010 at 2:27 pm
    Hi!
    Nice RFC, just an idea for an alternative syntax (added to the RFC as #2):

    property Hours {
    get { return $this->seconds / 3600; }
    set { $this->seconds = $value * 3600; } // The variable $value holds
    the incoming value to be "set"
    }

    class TimePeriod
    {
    private $seconds;

    public [Hours] $hours1;
    public {use Hours;} $hours2;
    }
    If you change "property" to "class" or "trait" and "get" to "__get" you
    need almost no new syntax :)

    --
    Stanislav Malyshev, Software Architect
    SugarCRM: http://www.sugarcrm.com/
    (408)454-6900 ext. 227
  • Matthew Weier O'Phinney at Nov 29, 2010 at 2:55 pm

    On 2010-11-29, Stas Malyshev wrote:
    Nice RFC, just an idea for an alternative syntax (added to the RFC as #2):

    property Hours {
    get { return $this->seconds / 3600; }
    set { $this->seconds = $value * 3600; } // The variable $value holds
    the incoming value to be "set"
    }

    class TimePeriod
    {
    private $seconds;

    public [Hours] $hours1;
    public {use Hours;} $hours2;
    }
    If you change "property" to "class" or "trait" and "get" to "__get" you
    need almost no new syntax :)
    Not really. With __get() and __set(), it's entirely likely that the class into
    which the trait is mixed in might override this already -- and not take into
    account the properties. That would be quite a brittle solution.

    --
    Matthew Weier O'Phinney
    Project Lead | matthew@zend.com
    Zend Framework | http://framework.zend.com/
    PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc
  • Jonathan Bond-Caron at Nov 29, 2010 at 5:51 pm

    On Mon Nov 29 09:27 AM, Stas Malyshev wrote:
    Hi!
    Nice RFC, just an idea for an alternative syntax (added to the RFC
    as #2):
    property Hours {
    get { return $this->seconds / 3600; }
    set { $this->seconds = $value * 3600; } // The variable $value holds
    the incoming value to be "set"
    }

    class TimePeriod
    {
    private $seconds;

    public [Hours] $hours1;
    public {use Hours;} $hours2;
    }
    If you change "property" to "class" or "trait" and "get" to "__get"
    you need almost no new syntax :)
    Right, it looks the same but the subtle difference is 'property Hours'
    wouldn't be registered as a class. It's just container code for get(), set()
    methods that would get 'compiled' into opcodes in the class TimePeriod (the
    property exists vs. searching for it in runtime). So you can think of it as
    a special 'trait' that only applies to properties.

    The idea behind this syntax is you can move the 'property' definition out of
    the class so that you can test and re-use it somewhere else (like traits).

    That might not be problem if you can define properties in traits (needs to
    be explained in the RFC):
    trait TimeUnits {
    public property Seconds
    {
    get { return $this->seconds; }
    set { $this->seconds = $value; }// The variable $value holds the
    incoming value to be "set"
    }
    public property Minutes
    {
    get { return $this->seconds / 60; }
    set { $this->seconds = $value * 60; }
    }
    public property Hours
    {
    get { return $this->seconds / 3600; }
    set { $this->seconds = $value * 3600; }// The variable $value holds
    the incoming value to be "set"
    }
    }

    class MyTime {
    uses TimeUnits;

    protected $_seconds;
    }
  • Larry at Nov 29, 2010 at 6:14 pm

    On 11/29/10 11:51 AM, Jonathan Bond-Caron wrote:

    Right, it looks the same but the subtle difference is 'property Hours'
    wouldn't be registered as a class. It's just container code for get(), set()
    methods that would get 'compiled' into opcodes in the class TimePeriod (the
    property exists vs. searching for it in runtime). So you can think of it as
    a special 'trait' that only applies to properties.

    The idea behind this syntax is you can move the 'property' definition out of
    the class so that you can test and re-use it somewhere else (like traits).

    That might not be problem if you can define properties in traits (needs to
    be explained in the RFC):
    I think I'd prefer to use Traits for externally-defined properties
    rather than defining a new top-level construct. It's fewer moving parts
    and we don't need to figure out how autoloading would be affected.
    (Autoload would work the same way it does now for traits... whatever
    that is.)

    That would then imply we do need to be able to declare the existence of
    a property and whether it has get, set, or both independently of the
    definition, just like methods, so that we can have a proper
    interface/trait split for properties just as for methods.

    --Larry Garfield
  • President at Nov 30, 2010 at 1:42 pm
    Hello,
    Hi!
    Nice RFC, just an idea for an alternative syntax (added to the RFC
    as #2):
    property Hours {
    get { return $this->seconds / 3600; }
    set { $this->seconds = $value * 3600; } // The variable $value holds
    the incoming value to be "set"
    }

    class TimePeriod
    {
    private $seconds;

    public [Hours] $hours1;
    public {use Hours;} $hours2;
    }
    If you change "property" to "class" or "trait" and "get" to "__get"
    you need almost no new syntax :)
    Right, it looks the same but the subtle difference is 'property Hours'
    wouldn't be registered as a class. It's just container code for get(),
    set()
    methods that would get 'compiled' into opcodes in the class TimePeriod
    (the
    property exists vs. searching for it in runtime). So you can think of it
    as
    a special 'trait' that only applies to properties.

    The idea behind this syntax is you can move the 'property' definition out
    of
    the class so that you can test and re-use it somewhere else (like traits).

    That might not be problem if you can define properties in traits (needs to
    be explained in the RFC):
    trait TimeUnits {
    public property Seconds
    {
    get { return $this->seconds; }
    set { $this->seconds = $value; }// The variable $value holds the
    incoming value to be "set"
    }
    public property Minutes
    {
    get { return $this->seconds / 60; }
    set { $this->seconds = $value * 60; }
    }
    public property Hours
    {
    get { return $this->seconds / 3600; }
    set { $this->seconds = $value * 3600; }// The variable $value
    holds
    the incoming value to be "set"
    }
    }

    class MyTime {
    uses TimeUnits;

    protected $_seconds;
    }

    I do not think that properties should make use of a trait-like syntax, as
    that is not what a property is about. A property is basically a layer of
    syntactic sugar over a pair of methods. The majority of the time when
    writing properties, you will not want to re-use them, so I have a hard
    time seeing many parallels to traits.

    However, it does make sense to be able to define a property as part of a
    trait, as again, it is basically just a pair of methods. When I get some
    time, I will try to add a syntax for traits to the RFC.

    - Dennis
  • Stefan Marr at Nov 30, 2010 at 1:50 pm
    Hi:
    On 30 Nov 2010, at 14:42, president@basnetworks.net wrote:

    However, it does make sense to be able to define a property as part of a
    trait, as again, it is basically just a pair of methods. When I get some
    time, I will try to add a syntax for traits to the RFC.
    The only thing really necessary for that would be a specification on how to name/to refer to the getter/setter to be able to handle the conflicts.
    The rest should work out of the box. As far as I can see from the proposal.

    Best regards
    Stefna

    - Dennis


    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
    --
    Stefan Marr
    Software Languages Lab
    Vrije Universiteit Brussel
    Pleinlaan 2 / B-1050 Brussels / Belgium
    http://soft.vub.ac.be/~smarr
    Phone: +32 2 629 2974
    Fax: +32 2 629 3525
  • Stas Malyshev at Nov 30, 2010 at 1:55 pm
    Hi!
    I do not think that properties should make use of a trait-like syntax, as
    that is not what a property is about. A property is basically a layer of
    syntactic sugar over a pair of methods. The majority of the time when
    writing properties, you will not want to re-use them, so I have a hard
    time seeing many parallels to traits.
    A side note: in PHP, property actually has four methods, not two -
    get/set/unset/isset.
    --
    Stanislav Malyshev, Software Architect
    SugarCRM: http://www.sugarcrm.com/
    (408)454-6900 ext. 227
  • President at Nov 30, 2010 at 2:15 pm
    Hello Stas,
    I do not think that properties should make use of a trait-like syntax,
    as
    that is not what a property is about. A property is basically a layer
    of
    syntactic sugar over a pair of methods. The majority of the time when
    writing properties, you will not want to re-use them, so I have a hard
    time seeing many parallels to traits.
    A side note: in PHP, property actually has four methods, not two -
    get/set/unset/isset.
    That is true for PHP variables. isset is basically saying "does this
    variable exist", and unset is saying to get rid of it.

    Because properties (as defined in my RFC) are not a variable, but rather a
    set of methods, I do not think there would be any way to "unset" them.
    Like a method, once they are defined, you cannot get rid of them.
    Therefore "overloading" isset and unset would not make any sense here.

    - Dennis
  • Johannes Schlüter at Nov 30, 2010 at 2:58 pm

    On Tue, 2010-11-30 at 09:15 -0500, president@basnetworks.net wrote:
    That is true for PHP variables. isset is basically saying "does this
    variable exist", and unset is saying to get rid of it.

    Because properties (as defined in my RFC) are not a variable, but rather a
    set of methods, I do not think there would be any way to "unset" them.
    Like a method, once they are defined, you cannot get rid of them.
    Therefore "overloading" isset and unset would not make any sense here.
    This is different from the PHP Language then. You can isset() and
    unset() "native" properties. And use __isset() and __unset() magic
    methods.

    A new feature should be consistent with the language definition.

    johannes
  • President at Dec 1, 2010 at 12:29 am

    That is true for PHP variables. isset is basically saying "does this
    variable exist", and unset is saying to get rid of it.

    Because properties (as defined in my RFC) are not a variable, but rather
    a
    set of methods, I do not think there would be any way to "unset" them.
    Like a method, once they are defined, you cannot get rid of them.
    Therefore "overloading" isset and unset would not make any sense here.
    This is different from the PHP Language then. You can isset() and
    unset() "native" properties. And use __isset() and __unset() magic
    methods.

    A new feature should be consistent with the language definition.
    Its not a matter of consistency - Properties, as a cross-language concept
    are not meant to work that way. You need to think of a property as a set
    of two methods that just have a pretty syntax. Methods cannot be unset,
    and nor should properties be allowed to. isset() should simply tell us
    whether a property with the specified name is part of the class or not.

    isset() in the way you suggest would just be confusing. It would allow is
    to say that a property does not exist, when in fact it does exist. This
    is not logical.

    __isset() is a whole different matter, without it we would have to assume
    that every possible member name either exists or does not exist. This is
    because __isset can handle ANY member name.

    Properties are bound to a single member name, therefore, they always
    exist, unless you were to physically remove that property from the class,
    which, like methods, that is not possible.

    - Dennis
  • Larry at Dec 1, 2010 at 1:09 am

    On 11/30/10 6:29 PM, president@basnetworks.net wrote:
    That is true for PHP variables. isset is basically saying "does this
    variable exist", and unset is saying to get rid of it.

    Because properties (as defined in my RFC) are not a variable, but rather
    a
    set of methods, I do not think there would be any way to "unset" them.
    Like a method, once they are defined, you cannot get rid of them.
    Therefore "overloading" isset and unset would not make any sense here.
    This is different from the PHP Language then. You can isset() and
    unset() "native" properties. And use __isset() and __unset() magic
    methods.

    A new feature should be consistent with the language definition.
    Its not a matter of consistency - Properties, as a cross-language concept
    are not meant to work that way. You need to think of a property as a set
    of two methods that just have a pretty syntax. Methods cannot be unset,
    and nor should properties be allowed to. isset() should simply tell us
    whether a property with the specified name is part of the class or not.

    isset() in the way you suggest would just be confusing. It would allow is
    to say that a property does not exist, when in fact it does exist. This
    is not logical.
    Consistency with other languages must also be balanced against
    consistency within PHP. Both are important.

    Class members and both existing class-member-ish mechanisms (__magic and
    ArrayAccess) have the concept of isset/unset. A third class-member-ish
    (syntactically speaking) mechanism will be expected to have the same set
    of primitives. To not have them will be a major language WTF, because
    to a normal user of an object they *look* like class members, not
    methods, they *taste* like class members, not methods, so they should
    *act* like class members, not methods.

    Basically, properties can only be considered a drop-in replacement for
    class members (as you've stated, correctly, is one of the potential big
    wins for them) if they fully emulate their behavior. If they do not,
    then it is incorrect to say that they can be swapped in for a class
    member without changing an API.
    __isset() is a whole different matter, without it we would have to assume
    that every possible member name either exists or does not exist. This is
    because __isset can handle ANY member name.

    Properties are bound to a single member name, therefore, they always
    exist, unless you were to physically remove that property from the class,
    which, like methods, that is not possible.
    No, but it can be easily emulated.

    Actually, I can even think of a concrete use case. Suppose I have an
    object that acts as a facade for a remote object over SOAP, REST, or
    whatever. It is using properties to represent attributes of a remote,
    say, insurance account. I want to know if a beneficiary has been set on
    the account. The most straightforward way to do so is

    if (isset($account->beneficiary)) {
    print $account->beneficiary->name;
    }

    If we are implementing such logic via __get(), we can do exactly that.

    If we are implementing it via properties, we should still be able to.
    Forcing the user to know that he needs to do it this way instead, but
    only if we're using properties rather than __get():

    if ($account->hasBeneficiary()) {
    print $account->beneficiary->name;
    }

    is violating the principle of encapsulation as it means the user needs
    to know which of the three forms of $account->beneficiary happens to be
    in use.


    Thinking about properties further, actually, there's two other (related)
    considerations that always give me grief when dealing with __get:
    Reference returns and complex member variables.

    If I want a reference to a class member, I can very easily do this:

    $foo = &$bar->baz;

    If ->baz is accessed via __get(), then that only works if __get() is
    defined as function &__get($var) to start with. That's another
    encapsulation break.

    Similarly, the following does exactly what you'd expect with a normal
    class member:

    $foo->bar['baz']->narf = 'poink';

    If $foo->bar is returned via __get(), though, then the above statement
    executes but does not actually save anything... *unless* __get() was
    defined to return by reference as above.

    Details of my adventures in __get() insanity here, including performance
    considerations:

    http://www.garfieldtech.com/blog/magical-php-call

    How would properties deal with those scenarios? (The answer may well be
    "it doesn't, screw off, that's way too esoteric", as it is for __get(),
    but we should at least consider if it's possible to handle those
    gracefully.)

    --Larry Garfield
  • Stas Malyshev at Nov 30, 2010 at 3:01 pm
    Hi!
    That is true for PHP variables. isset is basically saying "does this
    variable exist", and unset is saying to get rid of it.
    This is also true for object properties - see magic methods. I don't see
    why you shouldn't be able to unset them - you can do that with regular
    properties... So what you imagine would happen if you call
    unset($foo->property) or isset($foo->property)?

    --
    Stanislav Malyshev, Software Architect
    SugarCRM: http://www.sugarcrm.com/
    (408)454-6900 ext. 227
  • President at Dec 1, 2010 at 12:31 am

    That is true for PHP variables. isset is basically saying "does this
    variable exist", and unset is saying to get rid of it.
    This is also true for object properties - see magic methods. I don't see
    why you shouldn't be able to unset them - you can do that with regular
    properties... So what you imagine would happen if you call
    unset($foo->property) or isset($foo->property)?
    As I replied elsewhere:

    Its not a matter of consistency - Properties, as a cross-language concept
    are not meant to work that way. You need to think of a property as a set
    of two methods that just have a pretty syntax. Methods cannot be unset,
    and nor should properties be allowed to. isset() should simply tell us
    whether a property with the specified name is part of the class or not.

    isset() in the way you suggest would just be confusing. It would allow is
    to say that a property does not exist, when in fact it does exist. This
    is not logical.

    __isset is a whole different matter, without it we would have to assume
    that every possible member name in a class either exists or does not
    exist. This is because __isset, __get, __set and __unset can handle ANY
    member name.

    Properties are bound to a single member name, therefore, they always
    exist, unless you were to physically remove that property from the class,
    which, like methods, that is not possible.

    - Dennis
  • Davey Shafik at Dec 1, 2010 at 3:02 am
    Object properties (or members, classic ->var, not this proposed syntax) CURRENTLY, work this way:

    php -r 'class foo { public $bar; } $foo = new foo(); var_dump(isset($foo->bar));'
    bool(false)

    This is because you are confusing PHP's isset() with a property_exists(). Is set. Is the variable (or member/property)
    set to a value?

    In this case, both isset() and unset() work with the property get/set you are proposing. Imagine:

    $results = $db->query('SELECT SQL_CALC_FOUND_ROWS * FROM some_table WHERE foo = 'bar');

    if (isset($results->count)) {
    foreach ($results->getResult() as $result) {
    // Do something
    }
    }

    where isset() would hit:

    protected property count {
    isset {
    $result = $this->execute('SELECT FOUND_ROWS()');
    $this->count = $result->getColumn();
    if ($this->count == 0) {
    return false;
    }
    return false;
    }
    }

    Not an ideal example, but it gives you an IDEA off the top of my head of a way to take advantage of it

    - Davey
    On Nov 30, 2010, at 7:31 PM, president@basnetworks.net wrote:

    That is true for PHP variables. isset is basically saying "does this
    variable exist", and unset is saying to get rid of it.
    This is also true for object properties - see magic methods. I don't see
    why you shouldn't be able to unset them - you can do that with regular
    properties... So what you imagine would happen if you call
    unset($foo->property) or isset($foo->property)?
    As I replied elsewhere:

    Its not a matter of consistency - Properties, as a cross-language concept
    are not meant to work that way. You need to think of a property as a set
    of two methods that just have a pretty syntax. Methods cannot be unset,
    and nor should properties be allowed to. isset() should simply tell us
    whether a property with the specified name is part of the class or not.

    isset() in the way you suggest would just be confusing. It would allow is
    to say that a property does not exist, when in fact it does exist. This
    is not logical.

    __isset is a whole different matter, without it we would have to assume
    that every possible member name in a class either exists or does not
    exist. This is because __isset, __get, __set and __unset can handle ANY
    member name.

    Properties are bound to a single member name, therefore, they always
    exist, unless you were to physically remove that property from the class,
    which, like methods, that is not possible.

    - Dennis


    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
  • President at Dec 1, 2010 at 12:56 pm
    Hi Davey,
    Object properties (or members, classic ->var, not this proposed syntax)
    CURRENTLY, work this way:

    php -r 'class foo { public $bar; } $foo = new foo();
    var_dump(isset($foo->bar));'
    bool(false)

    This is because you are confusing PHP's isset() with a property_exists().
    Is set. Is the variable (or member/property)
    set to a value?
    I did not know of property_exists(), very interesting!

    In this case, both isset() and unset() work with the property get/set you
    are proposing. Imagine:

    $results = $db->query('SELECT SQL_CALC_FOUND_ROWS * FROM some_table WHERE
    foo = 'bar');

    if (isset($results->count)) {
    foreach ($results->getResult() as $result) {
    // Do something
    }
    }

    where isset() would hit:

    protected property count {
    isset {
    $result = $this->execute('SELECT FOUND_ROWS()');
    $this->count = $result->getColumn();
    if ($this->count == 0) {
    return false;
    }
    return false;
    }
    }

    Not an ideal example, but it gives you an IDEA off the top of my head of a
    way to take advantage of it
    Well, I understand the concept and how it would work, but I just don't
    think its logical. In my mind, being able to make a property appear to
    disappear makes as much sense as making a class method appear to
    disappear. This is absolutely no good for inheritance for one thing.

    The __isset method makes perfect sense, because all variables handled with
    __get and __set don't truly exist. They are not actually defined in the
    class, they are just "fake" class members, whose data comes from somewhere
    else - maybe an array. So __isset is there to say which "fake" member
    names do and don't exist.

    But when defined, a property, like a method, shouldn't be able to just
    "disappear". It is a specific definition and should never appear to be
    missing. If you need a class member that can be unset, you should be
    using __isset __get and __set, because that is exactly what those are
    meant for.


    My feelings are that a property "foo" should behave exactly like a
    getFoo() and setFoo($value) pair of methods. You can always call these
    methods, and never worry that you will get a "method not set" error. When
    you call getFoo() you are always guaranteed to get something, even if it
    is simply NULL.

    Maybe I am missing your point? But it does not make logical sense to me,
    the way you suggest.

    Also, would adding isset not make properties much slower? Calling
    $object->foo would first have to call and process the "isset" method to
    determine if it is set, then after getting "true" from isset, it would be
    able to call "get". And what happens if there is no "isset"? Is it just
    always guaranteed to be set then?

    - Dennis
  • Stefan Marr at Dec 1, 2010 at 7:59 am
    Hi:
    On 01 Dec 2010, at 01:31, president@basnetworks.net wrote:

    That is true for PHP variables. isset is basically saying "does this
    variable exist", and unset is saying to get rid of it.
    This is also true for object properties - see magic methods. I don't see
    why you shouldn't be able to unset them - you can do that with regular
    properties... So what you imagine would happen if you call
    unset($foo->property) or isset($foo->property)?
    Its not a matter of consistency - Properties, as a cross-language concept
    are not meant to work that way.
    I tend to disagree.
    The need to be consistent inside of PHP has precedence over being consistent with other languages.

    You need to think of a property as a set
    of two methods that just have a pretty syntax. Methods cannot be unset,
    and nor should properties be allowed to. isset() should simply tell us
    whether a property with the specified name is part of the class or not.
    I think, it really is the other way around.
    Properties are meant to give the programmer the illusion that she is just having a field.
    That is abstraction. She does not care about implementation details.
    And that is the power of properties.

    isset() and unset() are perfectly fine in that context.
    And I do not see a problem to provide the standard semantics for them automatically, and let the programmer add isset/unset methods to the property as needed in exactly the same style as get/set.

    There is a good usecase for asking whether a property has been set, for instance to verify initialization.
    And, of course unset has also a useful meaning. It is about the value, and even so there are methods around a value, properties are meant to be values.
    There are definitely use-cases where that does not hold, but that is application specific.

    isset() in the way you suggest would just be confusing. It would allow is
    to say that a property does not exist, when in fact it does exist. This
    is not logical.
    From the docu: isset — Determine if a variable is set and is not NULL
    There is nothing confusing about isset($this->Hours) == FALSE in your example if isset($this->seconds) == FALSE.

    Best regards
    Stefan

    --
    Stefan Marr
    Software Languages Lab
    Vrije Universiteit Brussel
    Pleinlaan 2 / B-1050 Brussels / Belgium
    http://soft.vub.ac.be/~smarr
    Phone: +32 2 629 2974
    Fax: +32 2 629 3525
  • President at Dec 1, 2010 at 1:10 pm

    That is true for PHP variables. isset is basically saying "does this
    variable exist", and unset is saying to get rid of it.
    This is also true for object properties - see magic methods. I don't
    see
    why you shouldn't be able to unset them - you can do that with regular
    properties... So what you imagine would happen if you call
    unset($foo->property) or isset($foo->property)?
    Its not a matter of consistency - Properties, as a cross-language
    concept
    are not meant to work that way.
    I tend to disagree.
    The need to be consistent inside of PHP has precedence over being
    consistent with other languages.
    Unfortunately I find that to be one of the major downfalls of PHP. It
    sometimes disregards defacto standards that are set across the entire
    industry, which causes a lot of frustration for new programmers.
    Sometimes the functionality PHP adds by going its own way is worth it, but
    often it is just a confusing mess. Thats just my opinion though, YMMV.

    You need to think of a property as a set
    of two methods that just have a pretty syntax. Methods cannot be unset,
    and nor should properties be allowed to. isset() should simply tell us
    whether a property with the specified name is part of the class or not.
    I think, it really is the other way around.
    Properties are meant to give the programmer the illusion that she is just
    having a field.
    That is abstraction. She does not care about implementation details.
    And that is the power of properties.

    isset() and unset() are perfectly fine in that context.
    And I do not see a problem to provide the standard semantics for them
    automatically, and let the programmer add isset/unset methods to the
    property as needed in exactly the same style as get/set.

    There is a good usecase for asking whether a property has been set, for
    instance to verify initialization.
    And, of course unset has also a useful meaning. It is about the value, and
    even so there are methods around a value, properties are meant to be
    values.
    There are definitely use-cases where that does not hold, but that is
    application specific.

    isset() in the way you suggest would just be confusing. It would allow
    is
    to say that a property does not exist, when in fact it does exist. This
    is not logical.
    From the docu: isset — Determine if a variable is set and is not NULL
    There is nothing confusing about isset($this->Hours) == FALSE in your
    example if isset($this->seconds) == FALSE.
    Right, I understand how it would work, and the reasons why it would "make
    sense", but it just feels wrong to me. When you unset() a variable in a
    class, that whole variable is gone. Its not just hiding somewhere, its
    completely gone. If a property were to "pretend" it is not set, with an
    isset method, it would still be there - just hiding. That is why it does
    not make sense to me.

    - Dennis
  • Stefan Marr at Dec 1, 2010 at 2:01 pm

    On 01 Dec 2010, at 14:10, president@basnetworks.net wrote:
    Unfortunately I find that to be one of the major downfalls of PHP. It
    sometimes disregards defacto standards that are set across the entire
    industry, which causes a lot of frustration for new programmers.
    Sometimes the functionality PHP adds by going its own way is worth it, but
    often it is just a confusing mess. Thats just my opinion though, YMMV.
    Still, if it is not consistent in itself it is worse than not following certain designs which make sense for other languages only.
    isset() in the way you suggest would just be confusing. It would allow
    is
    to say that a property does not exist, when in fact it does exist. This
    is not logical.
    From the docu: isset — Determine if a variable is set and is not NULL
    There is nothing confusing about isset($this->Hours) == FALSE in your
    example if isset($this->seconds) == FALSE.
    Right, I understand how it would work, and the reasons why it would "make
    sense", but it just feels wrong to me. When you unset() a variable in a
    class, that whole variable is gone. Its not just hiding somewhere, its
    completely gone. If a property were to "pretend" it is not set, with an
    isset method, it would still be there - just hiding. That is why it does
    not make sense to me.
    The main problem here is that unset and isset are not symmetric.

    isset() basically means there is a value.
    Where unset() destroys the _holder_ of the value.

    In that sense, unset is special since it works on another level, on the same level as property_exists().

    There are several possible approaches, but the main point here is that at least isset() still makes sense.
    property_exists() and unset() should be dealt with carefully in another way.

    Best regards
    Stefan

    --
    Stefan Marr
    Software Languages Lab
    Vrije Universiteit Brussel
    Pleinlaan 2 / B-1050 Brussels / Belgium
    http://soft.vub.ac.be/~smarr
    Phone: +32 2 629 2974
    Fax: +32 2 629 3525
  • President at Dec 2, 2010 at 2:13 pm
    Hi Stefan,
    Unfortunately I find that to be one of the major downfalls of PHP. It
    sometimes disregards defacto standards that are set across the entire
    industry, which causes a lot of frustration for new programmers.
    Sometimes the functionality PHP adds by going its own way is worth it,
    but
    often it is just a confusing mess. Thats just my opinion though, YMMV.
    Still, if it is not consistent in itself it is worse than not following
    certain designs which make sense for other languages only.
    Yes, I would agree with that.

    isset() in the way you suggest would just be confusing. It would
    allow is
    to say that a property does not exist, when in fact it does exist.
    This is not logical.
    From the docu: isset — Determine if a variable is set and is not NULL
    There is nothing confusing about isset($this->Hours) == FALSE in your
    example if isset($this->seconds) == FALSE.
    Right, I understand how it would work, and the reasons why it would "make
    sense", but it just feels wrong to me. When you unset() a variable in a
    class, that whole variable is gone. Its not just hiding somewhere, its
    completely gone. If a property were to "pretend" it is not set, with an
    isset method, it would still be there - just hiding. That is why it
    does not make sense to me.
    The main problem here is that unset and isset are not symmetric.

    isset() basically means there is a value.
    Where unset() destroys the _holder_ of the value.

    In that sense, unset is special since it works on another level, on the
    same level as property_exists().

    There are several possible approaches, but the main point here is that at
    least isset() still makes sense.
    property_exists() and unset() should be dealt with carefully in another
    way.
    Ok. Well isset() could just run the get handler for the property, and if
    it is null, return false, and otherwise return true.

    - Dennis
  • Johannes Schlüter at Dec 1, 2010 at 8:50 am

    On Tue, 2010-11-30 at 19:31 -0500, president@basnetworks.net wrote:

    isset() in the way you suggest would just be confusing. It would
    allow is
    to say that a property does not exist, when in fact it does exist.
    This
    is not logical.
    Even when a property does exist physically (by these "methods") it might
    not exist logically.

    Missing that functionality is inconsistent with the languages. such an
    inconsistency would be enough reason for a -1000 vote :-)

    johannes
  • Stas Malyshev at Dec 1, 2010 at 9:23 am
    Hi!
    Its not a matter of consistency - Properties, as a cross-language concept
    are not meant to work that way. You need to think of a property as a set
    Meant by whom? Is there some law of universe that prevents us from
    implementing the feature?
    of two methods that just have a pretty syntax. Methods cannot be unset,
    and nor should properties be allowed to. isset() should simply tell us
    whether a property with the specified name is part of the class or not.
    If you need methods, why not use methods? If you mimick object
    properties, however, it makes sense to make them work exactly like
    property, otherwise you have to explain why they don't work this way.
    isset() in the way you suggest would just be confusing. It would allow is
    to say that a property does not exist, when in fact it does exist. This
    is not logical.
    Sorry, from your answer I don't understand - what happens when you call
    isset($foo->property) and unset($foo->property)?
    --
    Stanislav Malyshev, Software Architect
    SugarCRM: http://www.sugarcrm.com/
    (408)454-6900 ext. 227
  • Richard Quadling at Dec 1, 2010 at 9:57 am

    On 1 December 2010 09:22, Stas Malyshev wrote:
    Hi!
    Its not a matter of consistency - Properties, as a cross-language concept
    are not meant to work that way.  You need to think of a property as a set
    Meant by whom? Is there some law of universe that prevents us from
    implementing the feature?
    of two methods that just have a pretty syntax.  Methods cannot be unset,
    and nor should properties be allowed to.  isset() should simply tell us
    whether a property with the specified name is part of the class or not.
    If you need methods, why not use methods? If you mimick object properties,
    however, it makes sense to make them work exactly like property, otherwise
    you have to explain why they don't work this way.
    isset() in the way you suggest would just be confusing.  It would allow is
    to say that a property does not exist, when in fact it does exist.  This
    is not logical.
    Sorry, from your answer I don't understand - what happens when you call
    isset($foo->property) and unset($foo->property)?
    If we think of properties as this new entity for the language (rather
    than somehow massaging existing entities to fit a new usage scenario),
    then

    isset($instance->property) will always return true for any defined
    property. Even if the getter would return null. This is new behaviour
    and can be easily documented. isset() for a property is more like
    method_exists() than isset() on a variable.
    With regard to unset($instance->property), from the manual ...

    "The behavior of unset() inside of a function can vary depending on
    what type of variable you are attempting to destroy."

    So, we already have differing behaviour based upon context. Attempting
    to destroy a property should through a non fatal error.

    One idea I had was to keep just the get/set property methods and add
    to them an additional parameter ...

    <?php
    public $seconds {
    public set($value, $unset = False) {
    if ($unset) {
    // unset() has been called on the property.
    // In this instance $value will be Null.
    } else {
    // set the property using the supplied $value.
    }
    },
    public get($isset = False) {
    if ($isset) {
    // isset() has been called on the property.
    // If the value is a non-destructive calculation then maybe
    returning the comparison of the result of the calculation to null.
    } else {
    // return the value for this property.
    }
    }
    };

    So,

    isset($instance->property) would call $instance->property->get(True);
    unset($instance->property) would call $instance->property->set(Null, True);

    This keeps just the 2 property methods. It still allows isset/unset
    and allows the developer the option of handling them.




    --
    Richard Quadling
    Twitter : EE : Zend
    @RQuadling : e-e.com/M_248814.html : bit.ly/9O8vFY
  • Eloy Bote Falcon at Dec 1, 2010 at 10:35 am
    2010/12/1 Eloy Bote Falcon <eloybote@gmail.com>
    2010/12/1 Richard Quadling <rquadling@gmail.com>
    On 1 December 2010 09:22, Stas Malyshev wrote:
    Hi!
    Its not a matter of consistency - Properties, as a cross-language
    concept
    are not meant to work that way. You need to think of a property as a
    set
    Meant by whom? Is there some law of universe that prevents us from
    implementing the feature?
    of two methods that just have a pretty syntax. Methods cannot be
    unset,
    and nor should properties be allowed to. isset() should simply tell us
    whether a property with the specified name is part of the class or not.
    If you need methods, why not use methods? If you mimick object
    properties,
    however, it makes sense to make them work exactly like property, otherwise
    you have to explain why they don't work this way.
    isset() in the way you suggest would just be confusing. It would allow
    is
    to say that a property does not exist, when in fact it does exist.
    This
    is not logical.
    Sorry, from your answer I don't understand - what happens when you call
    isset($foo->property) and unset($foo->property)?
    If we think of properties as this new entity for the language (rather
    than somehow massaging existing entities to fit a new usage scenario),
    then

    isset($instance->property) will always return true for any defined
    property. Even if the getter would return null. This is new behaviour
    and can be easily documented. isset() for a property is more like
    method_exists() than isset() on a variable.
    With regard to unset($instance->property), from the manual ...

    "The behavior of unset() inside of a function can vary depending on
    what type of variable you are attempting to destroy."

    So, we already have differing behaviour based upon context. Attempting
    to destroy a property should through a non fatal error.

    One idea I had was to keep just the get/set property methods and add
    to them an additional parameter ...

    <?php
    public $seconds {
    public set($value, $unset = False) {
    if ($unset) {
    // unset() has been called on the property.
    // In this instance $value will be Null.
    } else {
    // set the property using the supplied $value.
    }
    },
    public get($isset = False) {
    if ($isset) {
    // isset() has been called on the property.
    // If the value is a non-destructive calculation
    then maybe
    returning the comparison of the result of the calculation to null.
    } else {
    // return the value for this property.
    }
    }
    };

    So,

    isset($instance->property) would call $instance->property->get(True);
    unset($instance->property) would call $instance->property->set(Null,
    True);

    This keeps just the 2 property methods. It still allows isset/unset
    and allows the developer the option of handling them.




    --
    Richard Quadling
    Twitter : EE : Zend

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php

    Why change the expected behavior of isset? If a property has not been set
    then isset must return false, and that includes $foo->name = NULL.


    Regards.


    Oops, the mail has been marked has spam because of some URI.


    Regards.
  • Stas Malyshev at Dec 1, 2010 at 10:39 am
    Hi!
    If we think of properties as this new entity for the language (rather
    than somehow massaging existing entities to fit a new usage scenario),
    then
    I think the idea of new entity of the language looking exactly like old
    entity of the language but having different rules is kind of non-starter.
    One idea I had was to keep just the get/set property methods and add
    to them an additional parameter ...
    So we have one set of properties where get and isset use different
    methods and another set of properties where get and isset use same
    method but with parameter. I think it's not the best way to go. It's
    better to ignore isset altogether than this.
    --
    Stanislav Malyshev, Software Architect
    SugarCRM: http://www.sugarcrm.com/
    (408)454-6900 ext. 227
  • Richard Quadling at Dec 1, 2010 at 12:17 pm

    On 1 December 2010 10:38, Stas Malyshev wrote:
    So we have one set of properties where get and isset use different methods
    and another set of properties where get and isset use same method but with
    parameter. I think it's not the best way to go. It's better to ignore isset
    altogether than this.
    No. The prototype of all setters would be the same. As would the
    prototype of all getters.

    The prototype would be ...

    [public|protected|private] property $property {
    [public|protected|private] mixed|bool get([bool $isset = false]) {
    // mixed result for get, bool result for isset
    },
    [public|protected|private] mixed|void set(mixed $value [, bool
    $unset = false]) { // mixed result for set, void result for unset
    },
    };


    From a user's perspective ...

    echo isset($instance->property) ? 'isset to ' . $instance->property :
    'not isset';

    This would result in 2 calls ...

    property->get(true) // Let the getter that an attempt is being made to
    see if the property has been set.
    and
    property->get(false) // Let the getter know that the getter is
    expected to return the properties value.

    Similarly for the setter.

    $instance->property = 'foo';
    unset($instance->property);

    would result in 2 calls ...

    property->set('foo', false) // Let the setter know that it should be
    setting the value of the property to 'foo'.
    and
    property->set(null, true) // Let the setter know that an attempt to
    unset the property has taken place.



    Maybe the proposal should be changed to ...


    [public|protected|private] property $property {
    [public|protected|private] mixed get() {
    },
    [public|protected|private] mixed set(mixed $value) {
    },
    [public|protected|private] bool isset() {
    },
    [public|protected|private] void unset() {
    },
    };

    (NOTE: Add in abstract and final as appropriate).




    --
    Richard Quadling
    Twitter : EE : Zend
    @RQuadling : e-e.com/M_248814.html : bit.ly/9O8vFY
  • Stas Malyshev at Dec 1, 2010 at 12:31 pm
    Hi!
    No. The prototype of all setters would be the same. As would the
    prototype of all getters.
    But we'd have two sets of properties - one handled by __get/__isset,
    another - by get($isset). Not a good idea.

    --
    Stanislav Malyshev, Software Architect
    SugarCRM: http://www.sugarcrm.com/
    (408)454-6900 ext. 227
  • Richard Quadling at Dec 1, 2010 at 12:40 pm

    On 1 December 2010 12:30, Stas Malyshev wrote:
    Hi!
    No. The prototype of all setters would be the same. As would the
    prototype of all getters.
    But we'd have two sets of properties - one handled by __get/__isset, another
    - by get($isset). Not a good idea.
    So, should properties isset/unset go via the magic methods?

    With properties, there would be the duplication anyway (__get()/get()
    and __set()/set()).

    Either way, only the property knows what should happen when an isset()
    or unset() is called against it. It is for that reason that I think
    the property should handle it.

    __get, __set, __isset and __unset are for undefined class members. Not
    properties. From the user of the class, completely invisible.


    Having more than 1 way to skin the cat is pretty much de rigueur for PHP.




    --
    Richard Quadling
    Twitter : EE : Zend
    @RQuadling : e-e.com/M_248814.html : bit.ly/9O8vFY
  • President at Dec 2, 2010 at 2:02 pm

    So we have one set of properties where get and isset use different
    methods
    and another set of properties where get and isset use same method but
    with
    parameter. I think it's not the best way to go. It's better to ignore
    isset
    altogether than this.
    No. The prototype of all setters would be the same. As would the
    prototype of all getters.

    The prototype would be ...

    [public|protected|private] property $property {
    [public|protected|private] mixed|bool get([bool $isset = false]) {
    // mixed result for get, bool result for isset
    },
    [public|protected|private] mixed|void set(mixed $value [, bool
    $unset = false]) { // mixed result for set, void result for unset
    },
    };


    From a user's perspective ...

    echo isset($instance->property) ? 'isset to ' . $instance->property :
    'not isset';

    This would result in 2 calls ...

    property->get(true) // Let the getter that an attempt is being made to
    see if the property has been set.
    and
    property->get(false) // Let the getter know that the getter is
    expected to return the properties value.

    Similarly for the setter.

    $instance->property = 'foo';
    unset($instance->property);

    would result in 2 calls ...

    property->set('foo', false) // Let the setter know that it should be
    setting the value of the property to 'foo'.
    and
    property->set(null, true) // Let the setter know that an attempt to
    unset the property has taken place.



    Maybe the proposal should be changed to ...


    [public|protected|private] property $property {
    [public|protected|private] mixed get() {
    },
    [public|protected|private] mixed set(mixed $value) {
    },
    [public|protected|private] bool isset() {
    },
    [public|protected|private] void unset() {
    },
    };

    (NOTE: Add in abstract and final as appropriate).

    This last syntax makes far more sense than adding parameters to the
    get/set methods. The problem however, is what does isset and unset
    do/return if they are not defined? What if I only want to define the
    get/set and I do not define the isset/unset? If they are required,
    properties are far too complex to be useful. But if they are optional, we
    are back to the same problem of what isset() and unset() are supposed to
    do...

    - Dennis
  • Stefan Marr at Dec 1, 2010 at 10:42 am
    Hi Richard:
    On 01 Dec 2010, at 10:57, Richard Quadling wrote:
    If we think of properties as this new entity for the language (rather
    than somehow massaging existing entities to fit a new usage scenario),
    then

    isset($instance->property) will always return true for any defined
    property. Even if the getter would return null. This is new behaviour
    and can be easily documented. isset() for a property is more like
    method_exists() than isset() on a variable.
    I tend to see that rather different.
    Properties are not about methods, properties as in C# are about abstracting from the actual realization of how the state is represented internally that is exposed by a property.

    Thus, properties like proposed here should be used to provide the illusion of having normal class variables. And in that scenario it makes sense to talk about the value the property represents and not the fact that there are methods.

    So, from my point of view isset/unset have perfectly valid semantics on many of the usual cases.
    Even so, I agree, there are cases where that is not so, but in those cases isset/unset could be specialize like set/get.

    Best regards
    Stefan



    --
    Stefan Marr
    Software Languages Lab
    Vrije Universiteit Brussel
    Pleinlaan 2 / B-1050 Brussels / Belgium
    http://soft.vub.ac.be/~smarr
    Phone: +32 2 629 2974
    Fax: +32 2 629 3525

Related Discussions

People

Translate

site design / logo © 2022 Grokbase