Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP class def: Individual accessors/mutators or __set() with switch()?

When defining a PHP class, which is preferred/best practice? Are there any key differences I'm overlooking?

It seems like it could be more clean, concise, and convenient to write a __set() magic method and put a switch() construct in it with cases for all the private members to which I want to allow access. It wouldn't be called automagically from inside the class, but then again neither would setFoo(), so if I want to use the accessor/mutator internally, I'd have to explicitly call a method either way.

The other difference is that in the code outside the class, I could always access member vars in the same fashion as $obj->foo, whether public (directly) or private (using __set()), versus using many separate methods.

I guess this comes down mostly to an aesthetic choice. For example, if I have address data on a purchase, I don't want to have 16 or more separate accessor methods just for first name, last name, address1, address2, city, state, etc. each for shipping and billing data.

Are there any key differences I've overlooked? (Might a sophisticated IDE refuse to auto-complete a member name outside the class because it's marked as private?) Have I pretty much answered my own original question? Thanks in advance for your input.

like image 945
Wiseguy Avatar asked Oct 07 '09 11:10

Wiseguy


People also ask

What are accessors and mutators in PHP?

Accessors and mutators allow you to format Eloquent attributes when retrieving them from a model or setting their value. For example, you may want to use the Laravel encrypter to encrypt a value while it is stored in the database, and then automatically decrypt the attribute when you access it on an Eloquent model.

What will be the syntax of defining the class in PHP?

Basic class definitions begin with the keyword class , followed by a class name, followed by a pair of curly braces which enclose the definitions of the properties and methods belonging to the class. The class name can be any valid label, provided it is not a PHP reserved word.

How to use a class in PHP?

Key Aspects of a PHP ClassDefine a class with keyword “class” followed by name of the class. Define the constructor method using “__construct” followed by arguments. The object of the class can then be instantiated using “new ClassName( arguments_list )” Define class variables.


2 Answers

Go with the individual accessors for each and every member you want to be accessible from outside. I have tried both and found these reasons to use the accessors:

  • Whatever you use to document your API (doxygen/PHPdoc/Zend), the generated docs won't show the members that are accessible through magic functions.
  • You can document the accessors. You really ought to be able to put a line like this in the documentation: "IMPORTANT! This function connects to the database, it will be really slow, use otherFunction() if you can."
  • The implementation of the accessor is easily visible for anyone. I wouldn't want to dig into the details of a 200-line magic function to check if the accessor does anything besides setting/getting the value (that's why we're writing accessors after all.)
  • You already mentioned the autocompletion of IDEs.
  • The __get() function has a well-defined function header, so you won't be able to create getters that return a reference, for example (which is really great when working with arrays, i.e. $numbers = &$object->getNumbers(); $numbers[] = 4; - without the reference, you would need to call the setter again.)
like image 176
soulmerge Avatar answered Nov 02 '22 08:11

soulmerge


The biggest difference I see is with phpdoc :

  • using __set, you will not be able to generate phpdoc for each accessor
  • phpdoc being used by moderns IDE, this also means you will not get type-hinting nor code-completion if you use magic-methods (Using @property might help, though, on this point).

Personnaly, I would go with defining accessors myself, even if it means writing a bit more code :

  • no problem with phpdoc
  • you can use whatever parameters and return types you want
  • you explicitly indicate which methods can be used
  • easier to use specific code for each proerty, without have a really long __set method.

Also, I would use those accessor methods when setting properties from inside the class : it means a bit more code, yes -- but it also means going through the specific code (like code to check some stuff) they contain.

Finally, if you are just using some properties to store data, and don't need to define any specific behavior, why not expose them as public, and allow users to access those directly ?

like image 30
Pascal MARTIN Avatar answered Nov 02 '22 06:11

Pascal MARTIN