0

There are similar questions to this such as this but this is different - it's about validating constructor parameters using setters.

Here is my constructor:

public function __construct( $foo, $bar ) {
   try {
      $this->set_foo( $foo );
      $this->set_bar( $bar );
   } catch( Exception $e ) {
      echo 'Caught exception: ', $e->getMessage(), "\n"; 
   }
}

and here's one of the setters (pseudo-code):

public function set_foo( $foo ) {
   if( $foo fails validation checks ) {
      throw new InvalidArgumentException( '$foo is not valid' );
   }
}

In my class there are more than 2 class variables and each has their own set of validation checks. So is my question (well, 2 really):

Why would I want to change my code to use PHP magic getters/setters (here) and have a cluttered __set( $name, $value ) function? There would have to be a set of conditionals in this function to determine the type of validation that is needed so why would want to do this in this situation?

What is an example use case of these magic methods? Surely they would only be a good choice if there a few class members or when there is no validation?

Many thanks.

Community
  • 1
  • 1
ale
  • 11,636
  • 27
  • 92
  • 149
  • *(related)* [Using \_\_get Magic to emulate readonly properties](http://stackoverflow.com/questions/9342543/using-get-magic-to-emulate-readonly-properites-and-lazy-loading/9344438#9344438) – Gordon Oct 25 '12 at 08:43

3 Answers3

2

You shouldn't. IMO.

Magic setters are intended to access (set) private, protected or even virtual (non-existing) properties from outside the object.

If each one of your properties has different validation rules I can't see why you should inflate a single method in order to check them all. Better you keep your validation logic in different setter methods like you have it now.

EDIT

In the case you had some common validation rules, you should put them rules into non-public methods to re-use them from your setters.

Carlos
  • 4,949
  • 2
  • 20
  • 37
1

You could use it simply as convenience wrapper:

public function __set($name, $value) {
    $method = "set_$name";
    $this->$method($value);
}

That allows you to write $obj->foo = 'bar' instead of $obj->set_foo('bar').

Is it worth it? Maybe not. Especially since you still have to use $this->set_foo() inside the class. Nobody said you have to use magic setters.

deceze
  • 510,633
  • 85
  • 743
  • 889
1

I usually avoid the magic getters and setters in situations like this and have a specific getter and setter for each member that needs to be accessible. If you use a proper IDE or editor you can automatically generate the getters and setters so there's hardly any work to support the members that don't need any specific checks.

h00ligan
  • 1,471
  • 9
  • 17