<p>I'm going to try something with the format of this question and I'm very open to suggestions about a better way to handle it.</p>

<p>I didn't want to just dump a bunch of code in the question so I've posted the code for the class on <code>refactormycode</code>.</p>

<p><strong><a href="http://www.refactormycode.com/codes/461-base-class-for-easy-class-property-handling" rel="nofollow noreferrer">base class for easy class property handling</a></strong></p>

<p>My thought was that people can either post code snippets here or make changes on <code>refactormycode</code> and post links back to their refactorings.  I'll make upvotes and accept an answer (assuming there's a clear "winner") based on that.</p>

<p>At any rate, on to the class itself:</p>

<p>I see a lot of debate about getter/setter class methods and is it better to just access simple property variables directly or should every class have explicit get/set methods defined, blah blah blah.  I like the idea of having explicit methods in case you have to add more logic later.  Then you don't have to modify any code that uses the class.  However I hate having a million functions that look like this:</p>

<pre><code>public function getFirstName()
{
   return $this-&gt;firstName;
}
public function setFirstName($firstName)
{
   return $this-&gt;firstName;
}
</code></pre>

<p>Now I'm sure I'm not the first person to do this (I'm hoping that there's a better way of doing it that someone can suggest to me).</p>

<p>Basically, the PropertyHandler class has a __call magic method.  Any methods that come through __call that start with "get" or "set" are then routed to functions that set or retrieve values into an associative array.  The key into the array is the name of the calling method after getting or setting.  So, if the method coming into __call is "getFirstName", the array key is "FirstName".</p>

<p>I liked using __call because it will automatically take care of the case where the subclass already has a "getFirstName" method defined.  My impression (and I may be wrong) is that the __get &amp; __set magic methods don't do that.</p>

<p>So here's an example of how it would work:</p>

<pre><code>class PropTest extends PropertyHandler
{
    public function __construct()
    {
        parent::__construct();
    }
}

$props = new PropTest();

$props-&gt;setFirstName("Mark");
echo $props-&gt;getFirstName();
</code></pre>

<p>Notice that PropTest doesn't actually have "setFirstName" or "getFirstName" methods and neither does PropertyHandler.  All that's doing is manipulating array values.</p>

<p>The other case would be where your subclass is already extending something else.  Since you can't have true multiple inheritances in PHP, you can make your subclass have a PropertyHandler instance as a private variable.  You have to add one more function but then things behave in exactly the same way.</p>

<pre><code>class PropTest2
{
    private $props;

    public function __construct()
    {
        $this-&gt;props = new PropertyHandler();
    }

    public function __call($method, $arguments)
    {
        return $this-&gt;props-&gt;__call($method, $arguments);
    }
}

$props2 = new PropTest2();

$props2-&gt;setFirstName('Mark');
echo $props2-&gt;getFirstName();
</code></pre>

<p>Notice how the subclass has a __call method that just passes everything along to the PropertyHandler __call method.</p>

<hr>

<p>Another good argument against handling getters and setters this way is that it makes it really hard to document.</p>

<p>In fact, it's basically impossible to use any sort of document generation tool since the explicit methods to be don't documented don't exist.</p>

<p>I've pretty much abandoned this approach for now. It was an interesting learning exercise but I think it sacrifices too much clarity.</p>

[{'answer_id': 32191, 'author': 'Pat', 'author_id': 238, 'author_profile': 'https://Stackoverflow.com/users/238', 'pm_score': 3, 'selected': False, 'text': '<p>The way I do it is the following:</p>\n\n<pre><code>class test {\n    protected $x=\'\';\n    protected $y=\'\';\n\n    function set_y ($y) {\n        print "specific function set_y\\n";\n        $this-&gt;y = $y;\n    }\n\n    function __call($function , $args) {\n        print "generic function $function\\n";\n        list ($name , $var ) = split (\'_\' , $function );\n        if ($name == \'get\' &amp;&amp; isset($this-&gt;$var)) {\n            return $this-&gt;$var;\n        }\n        if ($name == \'set\' &amp;&amp; isset($this-&gt;$var)) {\n            $this-&gt;$var= $args[0];\n            return;\n        }\n        trigger_error ("Fatal error: Call to undefined method test::$function()");\n    }\n}\n\n$p = new test();\n$p-&gt;set_x(20);\n$p-&gt;set_y(30);\nprint $p-&gt;get_x();\nprint $p-&gt;get_y();\n\n$p-&gt;set_z(40);\n</code></pre>\n\n<p>Which will  output (line breaks added for clarity)</p>\n\n<pre><code>generic function set_x\nspecific function set_y\n\ngeneric function get_x\n20\ngeneric function get_y\n30\n\ngeneric function set_z\nNotice: Fatal error: Call to undefined method set_z() in [...] on line 16\n</code></pre>\n'}, {'answer_id': 32218, 'author': 'Pat', 'author_id': 238, 'author_profile': 'https://Stackoverflow.com/users/238', 'pm_score': 2, 'selected': False, 'text': "<p>Yes that's right the variables have to be manually declared but i find that better since I fear a typo in the setter </p>\n\n<pre><code>$props2-&gt;setFristName('Mark');\n</code></pre>\n\n<p>will auto-generate a new property (FristName instead of FirstName) which will make debugging harder.</p>\n"}, {'answer_id': 32219, 'author': 'Brian Warshaw', 'author_id': 1344, 'author_profile': 'https://Stackoverflow.com/users/1344', 'pm_score': 1, 'selected': False, 'text': '<p>I like having methods instead of just using public fields, as well, but my problem with PHP\'s default implementation (using __get() and __set()) or your custom implementation is that you aren\'t establishing getters and setters on a per-property basis. My problem with this is that adding "more logic later" requires that you add blanket logic that applies to all properties accessed with the getter/setter or that you use if or switch statements to evaluate which property you\'re accessing so that you can apply specific logic.</p>\n\n<p>I like your solution, and I applaud you for it--I\'m just not satisfied with the limitations that PHP has when it comes to implicit accessor methods.</p>\n'}, {'answer_id': 32356, 'author': 'Mark Biek', 'author_id': 305, 'author_profile': 'https://Stackoverflow.com/users/305', 'pm_score': 2, 'selected': False, 'text': '<p><a href="https://stackoverflow.com/questions/32145/is-this-a-reasonable-way-to-handle-getterssetters-in-a-php-class#32219">@Brian</a></p>\n\n<blockquote>\n  <blockquote>\n    <blockquote>\n      <blockquote>\n        <p>My problem with this is that adding "more logic later" requires that you add blanket logic that applies to all properties accessed with the getter/setter or that you use if or switch statements to evaluate which property you\'re accessing so that you can apply specific logic.</p>\n      </blockquote>\n    </blockquote>\n  </blockquote>\n</blockquote>\n\n<p>That\'s not quite true.  Take my first example:</p>\n\n<pre><code>class PropTest extends PropertyHandler\n{\n    public function __construct()\n    {\n        parent::__construct();\n    }\n}\n\n$props = new PropTest();\n\n$props-&gt;setFirstName("Mark");\necho $props-&gt;getFirstName();\n</code></pre>\n\n<p>Let\'s say that I need to add some logic for validating FirstNames.  All I have to do is add a setFirstName method to my subclass and that method is automatically used instead.</p>\n\n<pre><code>class PropTest extends PropertyHandler\n{\n    public function __construct()\n    {\n        parent::__construct();\n    }\n\n    public function setFirstName($name)\n    {\n        if($name == \'Mark\')\n        {\n            echo "I love you, Mark!";\n        }\n    }\n}\n</code></pre>\n\n<blockquote>\n  <blockquote>\n    <blockquote>\n      <blockquote>\n        <p>I\'m just not satisfied with the limitations that PHP has when it comes to implicit accessor methods.  </p>\n      </blockquote>\n    </blockquote>\n  </blockquote>\n</blockquote>\n\n<p>I agree completely.  I like the Python way of handling this (my implementation is just a clumsy rip-off of it).</p>\n'}, {'answer_id': 32405, 'author': 'Brian Warshaw', 'author_id': 1344, 'author_profile': 'https://Stackoverflow.com/users/1344', 'pm_score': 1, 'selected': False, 'text': "<p>@Mark</p>\n\n<p>But even your method requires a fresh declaration of the method, and it somewhat takes away the advantage of putting it in a method so that you can add more logic, because to add more logic requires the old-fashioned declaration of the method, anyway. In its default state (which is where it is impressive in what it detects/does), your technique is offering no advantage (in PHP) over public fields. You're restricting access to the field but giving carte blanche through accessor methods that don't have any restrictions of their own. I'm not aware that unchecked explicit accessors offer any advantage over public fields in <em>any</em> language, but people can and should feel free to correct me if I'm wrong.</p>\n"}, {'answer_id': 32507, 'author': 'reefnet_alex', 'author_id': 2745, 'author_profile': 'https://Stackoverflow.com/users/2745', 'pm_score': 0, 'selected': False, 'text': '<p>I\'ve always handled this issue in a similar with a __call which ends up pretty much as boiler plate code in many of my classes. However, it\'s compact, and uses the reflection classes to only add getters / setters for properties you have already set (won\'t add new ones). Simply adding the getter / setter explicitly will add more complex functionality. It expects to be </p>\n\n<p>Code looks like this:</p>\n\n<pre><code>/**\n* Handles default set and get calls\n*/\npublic function __call($method, $params) {\n\n    //did you call get or set\n    if ( preg_match( "|^[gs]et([A-Z][\\w]+)|", $method, $matches ) ) {\n\n        //which var?\n        $var = strtolower($matches[1]);\n\n        $r = new ReflectionClass($this);\n        $properties = $r-&gt;getdefaultProperties();\n\n        //if it exists\n        if ( array_key_exists($var,$properties) ) {\n            //set\n            if ( \'s\' == $method[0] ) {\n                $this-&gt;$var = $params[0];\n            }\n            //get\n            elseif ( \'g\' == $method[0] ) {\n                return $this-&gt;$var;\n            }\n        }\n    }\n}\n</code></pre>\n\n<p>Adding this to a class where you have declared default properties like: </p>\n\n<pre><code>class MyClass {\n    public $myvar = null;\n}\n\n$test = new MyClass;\n$test-&gt;setMyvar = "arapaho";\n\necho $test-&gt;getMyvar; //echos arapaho    \n</code></pre>\n\n<p>The reflection class may add something of use to what you were proposing. Neat solution @Mark.</p>\n'}, {'answer_id': 417966, 'author': 'Dan Soap', 'author_id': 25253, 'author_profile': 'https://Stackoverflow.com/users/25253', 'pm_score': 0, 'selected': False, 'text': "<p>Just recently, I also thought about handling getters and setters the way you suggested (the second approach was my favorite, i.e. the private $props array), but I discarded it for it wouldn't have worked out in my app.</p>\n\n<p>I am working on a rather large SoapServer-based application and the soap interface of PHP 5 injects the values that are transmitted via soap directly into the associated class, without bothering about existing or non-existing properties in the class.</p>\n"}, {'answer_id': 2658786, 'author': 'SeanJA', 'author_id': 75924, 'author_profile': 'https://Stackoverflow.com/users/75924', 'pm_score': 0, 'selected': False, 'text': '<p>I can\'t help putting in my 2 cents...</p>\n\n<p>I have taken to using <code>__get</code> and <code>__set</code> in this manor <a href="http://gist.github.com/351387" rel="nofollow noreferrer">http://gist.github.com/351387</a> (similar to the way that doctrine does it), then only ever accessing the properties via the <code>$obj-&gt;var</code> in an outside of the class. That way you can override functionality as needed instead of making a huge <code>__get</code> or <code>__set</code> function, or overriding <code>__get</code> and <code>__set</code> in the child classes.</p>\n'}]
['https://Stackoverflow.com/questions/32145', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/305/']