Pergunta

I am learning PHP object-oriented programming by watching a lot of video tutorials and reading a lot of articles in the process. Many of the PHP OOP tutorials I am seeing are say to use getters and setters. This made no sense to me; why I would make a class property as private or protected and then use a function to expose that property publicly? I started researching and found articles on here that now beg for this question:

Should you use getters and setters in PHP instead of accessing the properties of the class directly?

If yes, why? (Non-technical terms, please. Some of the other questions gave reasons, but they were so technical, I could not understand what they were attempting to explain)

If no, why not?

Note: While reading some similar Stack Overflow questions, I noticed this post written by Google developers.

Avoid writing naive setters and getters! When writing classes in PHP, you can save time and speed up your scripts by working with object properties directly, rather than writing naive setters and getters. In the following example, the dog class uses the setName() and getName() methods for accessing the name property.

Setting and calling the name property directly can run up to 100% faster, as well as cutting down on development time.

Google provided proof as to the speed impact that using them will have on your code.

Foi útil?

Solução

As my near-namesake says, the main purpose of getters and setters is side effects. The reason you would always use getters and setters is code maintainability.

Say you have a 10000+ lines-of-code project, and you have assignments to $foo->bar strewn all over. Then suddenly you decide you want to log every time foo's bar changes. With direct access, you need to go through your entire code base and find all the assignments. If you have a setter, it's a matter of adding a single line of code: nothing changes at the place the assignment is made.

Or, say you have an age property that is calculated in the constructor. Some time later, you decide it is not good enough; you want to calculate it every time you need it. This requires a function, direct access is not going to cut it. If you start with the direct access, you need to change every single instance of it into a function call. If you start with a trivial getter, you can change return $this->age into a date calculation or a database call or whatever you want by just modifying the getter: nothing else changes.

Ruby makes this into a general dogma: there are no public properties, only getters/setters (called accessors in the Ruby world), precisely because the only interaction allowed to the objects is message-passing (unless you employ magic). Ruby also makes creating trivial getters/setters... err, trivial, which makes it a negligible impact on development time. In PHP, you are given a choice.

Outras dicas

The main purpose of a getter/setter is when there is a "side effect".

For example, if you have an object that represents a database record, then you might write a setter for a property to have the side effect of updating the database behind the scenes. In other languages, setting the "left" property of a window (e.g. your webbrowser window) will move the window on the screen.

Or, if the value of a property is expensive to calculate or retrieve, you might not want to calculate the property if it is not needed; so you write a getter which calculates the property (and cache the result!).

Other examples include values that change too frequently to make it worth getting and storing (for example, how long ago something happened), which requires a getter, or where validation is required.

Also, sometimes 2 or more properties are interrelated, so setting one will effect the other. If you have a "rectangle" object, and set the "left" position and the "right" position, you want to be able to get the correct "width"; in other cases you might set the "left" and "width" property, and you want the value of "right" to be correct. To do this, you might not have an actual value for the "width" property, just a getter & setter; so when you set it, it updates the "right" property behind the scenes, and when you get it, it calculates the value from the "left" and "right" property.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top