Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.
public class PersonAge
{
private int age; // hidden variable
public int humanAge // public acces to variable
{
get // but you are able to write functions for the getting...
{
return age;
}
set // ...and setting of it, thus :)
{
age = value;
}
}
}
// Use it like this:
PersonAge fred;
System.Echo(fred.humanAge);
fred.humanAge = 20;
You can also omit a set or get block to make a variable read or write only.
Whoo, just realised that was my 500th post XD
Last edited by Ollie Saunders on Mon Aug 07, 2006 7:27 pm, edited 1 time in total.
public class PersonAge
{
private int age; // hidden variable
public int humanAge // public acces to variable
{
get // but you are able to write functions for the getting...
{
return age;
}
set // ...and setting of it, thus :)
{
age = value;
}
}
}
// Use it like this:
PersonAge fred;
System.Echo(fred.humanAge);
fred.humanAge = 20;
You can also omit a set or get block to make a variable read or write only.
Whoo, just realised that was my 500th post XD
In PHP, you CAN do this, but in a different way. Each language has its own syntax, and different ways of doing the same thing. It is also possible to make a variable read or write only also.
Well yes of course you can but personally I don't like lots of switches in my code and that is what you end up with if you expand your example into something more real world:
class Person
{
protected $_age;
protected $_firstName;
protected $_surname;
protected $_nationality;
protected $_id;
public function __get($name)
{
switch ($name) {
case 'age':
return $this->_age;
break;
case 'firstName':
return $this->_firstName;
break;
case 'surname':
return $this->_surname;
break;
case 'nationality':
return $this->_nationality;
break;
case 'id':
return $this->_id;
break;
default:
throw new Exception('Undefined property ' . $name);
}
}
public function __set($name, $value)
{
switch ($name) {
case 'age':
$this->_age = $value
break;
case 'firstName':
$this->_firstName = $value
break;
case 'surname':
$this->_surname = $value
break;
case 'nationality':
$this->_nationality = $value
break;
case 'id':
$this->_id = $value
break;
default:
throw new Exception('Undefined property ' . $name);
}
}
}
Obviously in the case of the example I gave there you would just do $this->{'_' . $name} = $value but this is assuming you want to write some specialist code for the setting and getting of each property.
Then also you have problems with inheritance. You can't choose which getter or setter to extend you have to override the whole __get() or __set() function; big problem. Having said all this, santosj has sucessfully drawn to may attention that this could be quite cool on a small scale. I had really just discounted it altogether.
class Person
{
private $age;
private $name;
private $sex;
private $parents;
private $children;
private $thoughts;
private function __get($aVar)
{
if(method_exists($this, 'get' . $aVar))
{
return call_user_func(array($this,'get' . $aVar));
}
elseif(property_exits($this, $aVar) and in_array($aVar, array('age','name','sex','parents','children'), true))
{
return $this->$aVar;
}
else
{
throw new UnknownProperty();
}
}
}
ole wrote:this is assuming you want to write some specialist code for the setting and getting of each property.
The above's fairly generic. So generic that it's basically what my Object class is built on.
ole wrote:Then also you have problems with inheritance. You can't choose which getter or setter to extend you have to override the whole __get() or __set() function;
I've just gone and had a look at my code to see if I could possibly implement Feyd's elegant solution. I have 26 function definitions begining with get and 8 with set. For some of them Feyd's solution would be good but for others I would rather keep them as methods and no allow them to be used as properties.
This is because when you call a method prefixed with get or set you know something is happening but when you use a property you think that you are just getting or setting that property. The difference is psychological but might change the way in which people use my objects and cause them to write code slower in performance. Not to mention there is the overhead of the __get() and __set() calls themselves.
I've just gone and had a look at my code to see if I could possibly implement Feyd's elegant solution. I have 26 function definitions begining with get and 8 with set. For some of them Feyd's solution would be good but for others I would rather keep them as methods and no allow them to be used as properties.
This is because when you call a method prefixed with get or set you know something is happening but when you use a property you think that you are just getting or setting that property. The difference is psychological but might change the way in which people use my objects and cause them to write code slower in performance. Not to mention there is the overhead of the __get() and __set() calls themselves.
I doubt the overhead is all that much. You do know that there is also a _call() magic method?
However, the point is that different languages gives you different ways to do tasks. Some tasks in Java can not be converted over, Multithreading and wouldn't make sense in a web language.
The nice thing about __call() or maybe not so nice depending on how you look at it, is that it won't use the __call() magic method if there is already a method that exists with that name.
santosj wrote:The nice thing about __call() or maybe not so nice depending on how you look at it, is that it won't use the __call() magic method if there is already a method that exists with that name.
.. unless permissions are set such that in the context being called, the method doesn't exist. e.g. a child calling a parent's private method would invoke __call() but calling a parent's protected or public method would not.