Page 1 of 3
Object variables
Posted: Fri Dec 31, 2004 7:30 am
by onion2k
Quick question. I have an object with a variable contained inside it. In order to change that variable would you prefer to:
1. Change it directly..
or
2. Use a method to change it..
Is there any sensible reason not to allow people to access to variables that are public directly? Using a method would allow me to validate things, but for the time being thats really not necessary.
Posted: Fri Dec 31, 2004 8:26 am
by n00b Saibot
i think 1st one is fast and mebbe 1st thing to do in place. using a method involves certain overheads as far as i know...
Posted: Fri Dec 31, 2004 8:42 am
by feyd
if you are going for object oriented code, then 2 is the only way, typically.
Posted: Fri Dec 31, 2004 9:22 am
by carlmcdade
Changing it directly might case problems later on with datatypes (is that a boolean 1 or a result 1?) and ruin the generic capabilities of the object. I would use a method even if it is a short as: return 1;
I cases where you have no idea where that variable is coming from you should strive to leave it in a state where it will not be set unstable by hardcoding. With a method you can check the datatype and other things before changing the value.
Re: Object variables
Posted: Wed Jan 05, 2005 3:35 am
by crouse
onion2k wrote:Is there any sensible reason not to allow people to access to variables that are public directly? Using a method would allow me to validate things, but for the time being thats really not necessary.
When you are working in an Object Oriented environment, using Objects, then it is not only sensible but it is standard. One of the main ideas behind OO is the abstraction of data. When creating an object the developer is trying to control how each of the private members are being used and accessed. Generally, each private variable in an object is has two associated public members that are used to get and set the value of that private variable. The programmer then can control how each variable is set and what values are acceptable. If a programmer wants to have a private variable be read only then the programmer can only specify a get method for that private variable. This makes it so that only internal methods have access to that variable.
Another scope type that should be considered when developing in an OO environment is protected when available like in languages like PHP. When a programmer uses the private scope modifier then only that class will have access to that variable or method. However, this poses a problem when you want to extend a base class into another class. If a programmer uses the protected scope modifier then all subclass will inherit that variable or method. Protected still makes the variable or method accessible internally and the programmer gets the protection of abstraction when interacting instantiated objects.
Hope this helps,
Chris
Posted: Sat Jan 14, 2006 12:39 pm
by jonathant
I am new at oop and php so please bear with me on this. If you are using a database what is the best way, practically, to implement what you are talking about? If you had a constructor that queried the database, would you then pass that data to private class variables? Then you could create public functions that would return those private variables and just call those functions on an instantiated object? Am I missing something critical?
Posted: Sat Jan 14, 2006 1:20 pm
by Jenk
Code: Select all
<?php
class MyClass
{
protected $myVar;
function getMyVar ()
{
return $myVar;
}
function setMyVar ($val)
{
$this->myVar = $val;
}
}
?>
Is the way I do it
If a class has lots of properties.. I sometimes get lazy.. but this is not a good practice, imo.
Code: Select all
<?php
class test
{
public $test;
function setObjVar ($var, $val)
{
if (array_key_exists($var, get_object_vars($this))) {
$this->{$var} = $val;
} else {
trigger_error('Invalid class (' . __CLASS__ . ') property specified: ' . $var . '!', E_USER_ERROR);
}
}
function getObjVar ($var)
{
if (array_key_exists($var, get_object_vars($this))) {
return $this->{$var};
} else {
trigger_error('Invalid class (' . __CLASS__ . ') property specified: ' . $var . '!', E_USER_ERROR);
}
}
}
$test = new test;
$test->setObjVar('test', 'yes');
print $test->getObjVar('test') . "\n";
?>
Posted: Sat Jan 14, 2006 2:04 pm
by alex.barylski
Jenk wrote:Code: Select all
<?php
class MyClass
{
[b]protected $myVar;[/b]
function getMyVar ()
{
return $myVar;
}
function setMyVar ($val)
{
$this->myVar = $val;
}
}
?>
Is the way I do it
If a class has lots of properties.. I sometimes get lazy.. but this is not a good practice, imo.
Code: Select all
<?php
class test
{
public $test;
function setObjVar ($var, $val)
{
if (array_key_exists($var, get_object_vars($this))) {
$this->{$var} = $val;
} else {
trigger_error('Invalid class (' . __CLASS__ . ') property specified: ' . $var . '!', E_USER_ERROR);
}
}
function getObjVar ($var)
{
if (array_key_exists($var, get_object_vars($this))) {
return $this->{$var};
} else {
trigger_error('Invalid class (' . __CLASS__ . ') property specified: ' . $var . '!', E_USER_ERROR);
}
}
}
$test = new test;
$test->setObjVar('test', 'yes');
print $test->getObjVar('test') . "\n";
?>
If your following proper OOP protocol and using data accessor's/mutator's why then, would you declare your member data as protected?
private would be a better choice...child classes would then be forced to use the appropriate member functions and you avoid ever directly accessing member data in derived objects.
Cheers

Re: Object variables
Posted: Sat Jan 14, 2006 2:08 pm
by alex.barylski
onion2k wrote:Quick question. I have an object with a variable contained inside it. In order to change that variable would you prefer to:
1. Change it directly..
or
2. Use a method to change it..
Is there any sensible reason not to allow people to access to variables that are public directly? Using a method would allow me to validate things, but for the time being thats really not necessary.
Depends who you ask...
OOP Zealots will always say number two...
I say number two
The problem I find with PHP is that every member function MUST be implemented inline and documenting trivial inlines (for the sake of API doc generation) to me...seems to add clutter, but I do it anyways

Posted: Sat Jan 14, 2006 2:19 pm
by Gambler
OOP Zealots will always say number two...
I'm OOP zealot (kind of), and I'd say 1 might not be such a bad idea in some cases.
First, it's much cleaner syntactically in case of complicated assignments:
Code: Select all
$obj->setVar($obj->getVar2());
//vs
$obj->var = $obj->var2;
Second, it might give you considerable speed avantage if you access variable thousands of times. Methods have overhead.
Also, it might worth checking __get and __set magic methods.
Re: Object variables
Posted: Sat Jan 14, 2006 3:14 pm
by Christopher
onion2k wrote:Is there any sensible reason not to allow people to access to variables that are public directly? Using a method would allow me to validate things, but for the time being thats really not necessary.
The "sensible reason" historically given to use a method rather than accessing properties directly was that it abstracts theaccess. By that I mean that if you need to change the behavior or do some processing of a property -- that is easily done using a method -- but can be a problem in PHP if you access them directly. What if, for example, you wanted to do bounds checking on a property when it was being set?
PHP5 provides an incomplete implementation to deal with this in the __get() and __set() magic methods. But there are some problems with those as well that will hopefully be fixed in the future
Getter/setters are also the way Java originally (sort of) required you to do it -- and we are influenced by Java whether we like it or not.
Also, there is a class of objects where you want properties to be accessed directly. Value Objects are the most common of these.
However, there is a whole separate but related discussion on whether getter and setter methods are a good idea at all. They are not very OO it ends up and not using them may improve your code. If you search for "getters and setters are evil" you will find a lot of discussion about this.
Posted: Sat Jan 14, 2006 3:58 pm
by alex.barylski
Gambler wrote:OOP Zealots will always say number two...
I'm OOP zealot (kind of), and I'd say 1 might not be such a bad idea in some cases.
First, it's much cleaner syntactically in case of complicated assignments:
Code: Select all
$obj->setVar($obj->getVar2());
//vs
$obj->var = $obj->var2;
Second, it might give you considerable speed avantage if you access variable thousands of times. Methods have overhead.
Also, it might worth checking __get and __set magic methods.
Kind of eh?
It's bad practice...IMHO and in those who founded the technology or are considered experts in the field...
In PHP you might have an argument...but in compiled languages like C++ getter/setter functions, when inlined basically just expand like a MACRO, so there is no function call overhead. No pushing and popping of the stack!
So historically, getter/setter methods are the prefered approach

Posted: Sat Jan 14, 2006 6:43 pm
by Buddha443556
It's bad practice...IMHO
I agree 1 is a bad practice.
- Creates a dependence on a perticular implementation.
- Other classes may need to be notified of the changes to the member variable.
- Breaks encapsulation.
Finding a public in production code is usually a good reason to stop and take a harder look.
Posted: Sat Jan 14, 2006 8:23 pm
by Jenk
Hockey wrote:
If your following proper OOP protocol and using data accessor's/mutator's why then, would you declare your member data as protected?
private would be a better choice...child classes would then be forced to use the appropriate member functions and you avoid ever directly accessing member data in derived objects.
Cheers

Abstract classes make the use of private not always appropriate, and using protected also allows the method's to be approriately overloaded/redefined if the child class requires they are to be done so.
As can be seen in this example:
Code: Select all
<?php
class A
{
private $var;
function setVar ($val)
{
$this->var = $val;
}
function getVar ()
{
return $this->var;
}
}
class B extends A
{
function setVar ($val)
{
$this->var = $val;
echo "done!\n";
}
}
$a = new A;
$b = new B;
$a->setVar('a');
$b->setVar('b');
print $a->getVar()."\n";
print $b->getVar()."\n";
?>
But yes.. private is preferable to protected - I was more hinting that I never use public, not that I always use protected.
Posted: Sat Jan 14, 2006 9:14 pm
by raghavan20
This is the problem about allowing some class to modify an important member variable and not actually about allowing some class to read the member variable. This example should highlight the importance.
Code: Select all
class BankAccount{
private $balance = 0.0;
public BankAccount(){
}
public getBalance(){
return $balance
}
private setBalance($balance){
$this->balance = $balance;
}
public modifyBalance($balance, $user, $date, $someNecessaryFields){
if (checkAllNecessaryConditionsSatisfied){
$this->setBalance($balance);
}else{
return false;
}
}
}
$accountInstance = new BankAccount();
$accountInstance->balance = 1000; //this should not be accessible
$accountInstance->modifyBalance(1000, $accepted_creditor, $date, $allOtherNecessaryFields);
$accountInstance->getBalance(); //this is how you should see the member variable