PHP: What are Getter and Setters? - php

What are getters and setters in PHP5?
Can someone give me a good example with an explanation?

This is concept for data hiding (or encapsulation) in OOP. For example if you want to have a certain property in your class let's say 'Amount' and give the client of you class the option to change or extract its value You should make your variable 'Amount' private (not visible for those who use your class) and generate two methods a getter and a setter that manipulates your value (that are public).
The reason is to be able to validate data or manipulate it before setting or getting your value. Here is a brief example:
class test {
private $count; //those who use your class are not able to see this property, only the methods above
public function setCount( $value )
{
//make some validation or manipulation on data here, if needed
$this->count = $value;
}
public function getCount()
{
return $this->count;
}
}

Attributes of classes can be private. That means only the object can read and write its own private attributes. Therefore you need methods to do that. The methods that read and return an attribute value are called getters and those that write attributes are called setters. With these methods the classes can control what’s going out and what’s coming in. This concept is called encapsulation.

Getters and Setters are quite new concept in PHP 5 in the form of two magical functions __get() and set(). These two functions set or get property value of an object dramatically as explained in the following example.
class Datatype{
private $thing;
public function _set($k,$v){
$this->$k = $v;
}
public function __get($k){
return $this->$k;
}
}

The PHP manual is really not very verbose on the issue, but there is a very detailed example that should explain a lot. Magic methods: Property overloading

Related

OOP generic practice (Symfony demo)

I have two simple questions regarding OOP practice of classes. I expect that the answers will lean toward subjective preferences.
Let's say we have a class like a blog POST, which has private variables such as id, author, etc. I see in Symfony demo project the getter and setter methods are declared for almost each variable specifically. If the list is long, this seems quite tedious. So what about creating a method like the following?
function setProp($variable, $val){
if($variable !== 'id'){
$this->$$variable = $val;
}
}
I see that the Symfony demo created three entity classes: Comment, Post, User. The addComment and removeComment methods are in Post class and takes a typecast argument of Comment class. Can we make a removeComment method in the Comment class itself? Because I feel that most of the time the comment id would be the first piece of info passed to the script, so why not have such a method handy in the class itself? And is it 'bad' to have repeated methods that perform the same job in different classes?
The purpose of accessor methods is to provide a way to hook into the action of setting or getting a property.
For basic operations, you don't need accessor methods. They may seem pointless just assigning or returning a value.
One of the main purposes of accessor methods is restricting access to a property. You may want, under some conditions, to prevent the changing of a property. If the property is public, there is nothing you can do to prevent writing to the property. But if your property is private and you have a setter, then you may just not set the property under certain conditions.
private $allowed = true;
private $data;
public function getData() {
return $this->data;
}
public function setData($data) {
if ($this->allowed) {
$this->data = $data;
}
}
public function block() {
$this->allowed = false;
}
In this example, you may block write-access to the data property by setting the allowed property to false.
There are many other cases that make use of accessors (storing data outside the object, converting values, etc.)
It is good practice to use setters and getters from the start because if you create them later, you have to replace all references to the property with references to the setter/getter.
you can look at magique method __set (http://php.net/manual/fr/language.oop5.overloading.php#object.set) but it's better to write each setXxxx

Should I use public setter to set private attribute value inside class?

Lets assume I have a class Test, which has got a private attribute called $_list, and a public setter.
Public setter is used to set the attribute value from the outside.
class Test {
private $_list;
public function getList() {
return $this->_list;
}
public function setList($list) {
$this->_list = $list;
}
public function initialize() {
$list = array();
/* ... Some code that fills the $list with values etc. ... */
// 1) Set value directly
$this->_list = $list;
// 2) Use public setter
$this->setList($list);
}
}
The question is - do I need to use public setter to set private attribute value inside class?
Which way is are better - #1 or #2? And why?
Which way do you prefer?
I would like to see a complete answer with the explaination of advantages and disadvantages of each way.
Thanks.
As it was written above, both are acceptable, but the correct answer is: Rather use the direct attribute access, but sometimes you better use the setters.
Number 1, (property access) Pros:
Easily readable and slighty faster
Gives you the approach that this is an simple attribute of the object
Number 2, (setter) Pros:
You can do custom action on setting the attribute (e.g. initialize other attributes, caches, or call a method on the parameter object)
You treat the attribute as a sub-element of the class, which may have own logic implemented.
I think that proposing that there is no logic behind using a variable is more important. If it is simple, make it look simple. If it's not, you can still use setters.
You could also ask the same about getters versus property access, the above applies as well.

OOP PHP and 'Get-Set'

I'm wondering is there anyway to create 'Get-Set' method only once that can be use to every attribute
The following code is not correct. Just to make sure you know what I'm looking for
class someClass {
private $attrA;
private $attrB;
private $attrC;
public function get($attr){
return $this->$attr;
}
public function set($attr, $value){
$this->$attr = $value;
}
}
Yes, you can use the magic methods __get() and __set() in the exact way you describe.
More info on the official web site.
Do you want public fields or public properties ?
In case you want properties, where an operation or validation is done when trying to read or trying to modify a property's value, then, I strongly recommend make individual "getter (s)" and individual "setter (s)" for your properties.
It looks difficult at first, but eventually it will make your code extensible and customizable...
Otherwise, just do plain public fields.

Should I use a setter within a class to set a property?

I want to set a property value within my class. I can do it without a setter and a getter but I want to know the "correct" way to approach this. This is for a login script so the property and the setter are both private.
Should I just set the property directly or use a setter and a getter?
This is probably mainly a matter of personnal preference...
If you have to set the private property from a method of the class, I would say that you can access that property directly.
A reason to use an setter/getter, in that kind of situation, would be if you want to ensure that some condition or calculation is made on the data each time the property is set.
As a sidenote : of course, if your want to access your private property from outside the class, you'll have to use to public setter/getter -- but it doesn't seem to be what you are trying to do here.
This is a matter of opinion. Traditional object oriented programming principles say Yes, but it's really up to you.
Note that you will have to use a setter method if you set your property to private. Setters should always be public, so that other classes and methods can operate on the property. If you don't have any reason to access the property from outside your class though, then don't create a setter, because it really won't matter; you'll always have access to private member variables / properties from within the class.
Don't forget that you can use the "magic" __get / __set methods without having to create getters and setters for everything.
magic functions
edit: If the member variables are private or protected you will have to use a getter and setter. If they are public, it's a matter of style - though you should be consistent with the rest of your class.
Setter/Getters allow derived classes to modify/limit/enhance state and behavior of an object more easily. But you can over-do setters/getters and then they become a bit annoying. (Especially in languages that do not hide them).
class Foo {
protected $x;
public function __construct($x) {
$this->setX($x);
}
public function setX($x) {
$this->x = $x;
}
public function something($y) {
// not using a getter here, it's only an example
echo $this->x * $y;
}
}
class DoubleFoo extends Foo {
public function setX($x) {
parent::setX($x*2);
}
}
$df = new DoubleFoo(1);
$df->something(5);

Is this a reasonable way to handle getters/setters in a PHP class?

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.
I didn't want to just dump a bunch of code in the question so I've posted the code for the class on refactormycode.
base class for easy class property handling
My thought was that people can either post code snippets here or make changes on refactormycode and post links back to their refactorings. I'll make upvotes and accept an answer (assuming there's a clear "winner") based on that.
At any rate, on to the class itself:
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:
public function getFirstName()
{
return $this->firstName;
}
public function setFirstName($firstName)
{
return $this->firstName;
}
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).
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".
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 & __set magic methods don't do that.
So here's an example of how it would work:
class PropTest extends PropertyHandler
{
public function __construct()
{
parent::__construct();
}
}
$props = new PropTest();
$props->setFirstName("Mark");
echo $props->getFirstName();
Notice that PropTest doesn't actually have "setFirstName" or "getFirstName" methods and neither does PropertyHandler. All that's doing is manipulating array values.
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.
class PropTest2
{
private $props;
public function __construct()
{
$this->props = new PropertyHandler();
}
public function __call($method, $arguments)
{
return $this->props->__call($method, $arguments);
}
}
$props2 = new PropTest2();
$props2->setFirstName('Mark');
echo $props2->getFirstName();
Notice how the subclass has a __call method that just passes everything along to the PropertyHandler __call method.
Another good argument against handling getters and setters this way is that it makes it really hard to document.
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.
I've pretty much abandoned this approach for now. It was an interesting learning exercise but I think it sacrifices too much clarity.
The way I do it is the following:
class test {
protected $x='';
protected $y='';
function set_y ($y) {
print "specific function set_y\n";
$this->y = $y;
}
function __call($function , $args) {
print "generic function $function\n";
list ($name , $var ) = split ('_' , $function );
if ($name == 'get' && isset($this->$var)) {
return $this->$var;
}
if ($name == 'set' && isset($this->$var)) {
$this->$var= $args[0];
return;
}
trigger_error ("Fatal error: Call to undefined method test::$function()");
}
}
$p = new test();
$p->set_x(20);
$p->set_y(30);
print $p->get_x();
print $p->get_y();
$p->set_z(40);
Which will output (line breaks added for clarity)
generic function set_x
specific function set_y
generic function get_x
20
generic function get_y
30
generic function set_z
Notice: Fatal error: Call to undefined method set_z() in [...] on line 16
#Brian
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.
That's not quite true. Take my first example:
class PropTest extends PropertyHandler
{
public function __construct()
{
parent::__construct();
}
}
$props = new PropTest();
$props->setFirstName("Mark");
echo $props->getFirstName();
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.
class PropTest extends PropertyHandler
{
public function __construct()
{
parent::__construct();
}
public function setFirstName($name)
{
if($name == 'Mark')
{
echo "I love you, Mark!";
}
}
}
I'm just not satisfied with the limitations that PHP has when it comes to implicit accessor methods.
I agree completely. I like the Python way of handling this (my implementation is just a clumsy rip-off of it).
Yes that's right the variables have to be manually declared but i find that better since I fear a typo in the setter
$props2->setFristName('Mark');
will auto-generate a new property (FristName instead of FirstName) which will make debugging harder.
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.
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.
#Mark
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 any language, but people can and should feel free to correct me if I'm wrong.
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
Code looks like this:
/**
* Handles default set and get calls
*/
public function __call($method, $params) {
//did you call get or set
if ( preg_match( "|^[gs]et([A-Z][\w]+)|", $method, $matches ) ) {
//which var?
$var = strtolower($matches[1]);
$r = new ReflectionClass($this);
$properties = $r->getdefaultProperties();
//if it exists
if ( array_key_exists($var,$properties) ) {
//set
if ( 's' == $method[0] ) {
$this->$var = $params[0];
}
//get
elseif ( 'g' == $method[0] ) {
return $this->$var;
}
}
}
}
Adding this to a class where you have declared default properties like:
class MyClass {
public $myvar = null;
}
$test = new MyClass;
$test->setMyvar = "arapaho";
echo $test->getMyvar; //echos arapaho
The reflection class may add something of use to what you were proposing. Neat solution #Mark.
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.
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.
I can't help putting in my 2 cents...
I have taken to using __get and __set in this manor http://gist.github.com/351387 (similar to the way that doctrine does it), then only ever accessing the properties via the $obj->var in an outside of the class. That way you can override functionality as needed instead of making a huge __get or __set function, or overriding __get and __set in the child classes.

Categories