Getters and Setters in classes

Hi,

I want to start using private variables as many members of this forum have seen my code before and have recommended me to use it as it’s good practice. So i’m starting off with the code below:


class Person{

  private $name = '';

  public function __construct($name){
    $this->name = $name;
  }

}

$person = new Person('john');

print $person->name;

I have a class, have a private variable and simply want to print out the name. Now normally what i would do is set the variable to public, but let’s say i want to access the name this way, how can i do it?

Thanks

I kind of wanted to simplify the code for purposes of faster understanding.
I wanted to illustrate how to use the setter to populate non-defined member and how to retrieve non-defined member. Sure, checks should be set in place, however for example’s sake - it’s not exactly clear what setter and getter do if you’re new to the whole deal.

What Anthony said is valid too - setters and getters attribute to code clarity (if used correctly).

But in the end, it’s way better to adhere to what you know and not use what you don’t understand since it can lead to bad usage (and terrible code). You don’t need a nuke to kill a fly :cool:

Stuffing everything into an array with publicly accessible values defeats the whole purpose of limiting the scope of properties to the object in the first place. Its OK in some cases where overloading is necessary like with generic data objects or something, but not for every class defined. Generic design is fine in moderation but making such a simple task generic just isn’t necessary unless dealing with a special case that warrants it such as generic data entities for an orm or something. The more concrete the interface is the less prone to error and easier to debug it will be.

Magical methods should be avoided when programming a concrete interface due to the efficiency implications.

False. Magic methods exist to ease the development. If your code takes 10 hours to type instead 6 hours but is faster for 0.001 second - what’s the point? If we’re talking in terms of web development, I disagree with you completely. Abandoning conventions for negligible performance gain is terrible practice.

They shouldn’t be avoided, they should be used where they are meant to be used and where they speed up the development time or maintainability of the project.
Avoiding a convention for the sake of saving negligible execution time is meaningless, no one will ever notice that. Computing power is incredibly cheap and available these days, optimizing on silly parts of the program is ridiculous.

I agree with the rest but I’ve to comment on one silly thing - I’ve seen many developers who are the sole developers of the project, meaning there’s no version control in place or branching etc. yet they enforce access control in their classes to the point it becomes a nightmare to retrieve a member. I just find it ridiculous to put these restrictions in place and heavy OO for simple projects that aren’t meant to be extended or have more than 1 person working on it at a time.

Consider thinking how to code something faster, efficient and easy to understand by the next guy rather than using every language construct that exists.

Magical methods should be avoided when programming a concrete interface due to the efficiency implications. Its common to see those methods in places where properties are dynamic but in your case its overkill considering name isn’t being overloaded at run-time. Also, it does no good to make everything private but accessible outside the object. You only want to make things accessible outside the object that must be. The more control that can be retained within the class the more maintainable and simplified the application as a whole will become that uses said functionality of the class to perform its duties.


class Person {

	private $name;
	
	public function __construct($name) {
		$this->name = $name;
	}
	
	public function getName() {
		return $this->name;
	}

}

$person = new Person('John');
echo '<p>',$person->getName(),'</p>';

Blue, I like your idea, but I would do it slightly differently:


<?php
Class Person 
{
	private $attributes;

	public function __construct() {}

	public function __set($name, $value)
	{
		if (in_array($name, $this->getAttributes()))
			$this->attributes[$name] = $value;
		else
			throw new Exception(get_class($this).' doesn\\'t have an attibute '.$name.'!');
	}

	public function __get($value)
	{
		if (in_array($name, $this->getAttributes()))
			return $this->attributes[$value];
		else
			throw new Exception(get_class($this).' doesn\\'t have an attibute '.$name.'!');
	}

	public function getAttributes()
	{
		return array('name', 'lastName');
	}       
}

$person = new Person();

$person->name = 'John';
$person->lname = 'Doe';

echo $person->name;

Of course you can do something else instead of throwing an exception (return false or whatever).
The idea is to prevent yourself from making typo’s. For example first I type $person->lastName, and some time later I try to access it with $person->last_name. The object won’t have any problem with that and this can make debugging a real pain. If the object “knows” which attributes to allow that problem disappears :slight_smile:

PS. This class would probably work better if it were abstract with no implementation for getAttributes() so that every extending class would have to override that function and will then be able to use the __set() / __get() functionality provided by the abstract class.

Thanks for the code! :wink:

And no it’s not peer pressure, other members of this forum have recommended me to look into it as code i have posted in the past isn’t quite right.

I think it’s just good to know and of course as you mentioned good to understand so i know when and where to use it.

Thanks again.

So you are inclined to use something that you don’t understand because of peer pressure? It’s questionable if it’s a good practice or not and you shouldn’t use it just because it “looks cool” or something like that and if your intended application isn’t such that you require getters and setters.

But to answer your question:

Class Person 
{
	private $name;
	
	public function __construct()
	{
	}
	
	public function __set($name, $value)
	{
		$this->name[$name] = $value;
	}
	
	public function __get($value)
	{
		return $this->name[$value];
	}
}

$person = new Person();

$person->name = 'John';
$person->lname = 'Doe';

echo $person->name; // echoes John 

I’m sure others will contribute their own interpretations of the provided example. Be sure to read upon what setter and getter actually do before using them.

Very surprised that no one has mentioned code clarity yet… However, I am a little concerned that we’re deviating off-topic a little. :cool:

Personally, I think that an object should be in full control of it’s own state, allowing public properties prevents this.

I often wonder if people avoid writing getters/setters just because it’s more code to write…

Read this for the benchmarks:
>> http://www.garfieldtech.com/blog/magic-benchmarks

(I still prefer __get & __set.)