Page 1 of 1
read only properties of an object in php4
Posted: Sat Apr 24, 2010 3:43 pm
by panic!
Is here any way of achieving this?
In php5 one could use __get and __set to abstract the user from the 'real' properties, does anyone know of a way of doing this using php4?
Re: read only properties of an object in php4
Posted: Sat Apr 24, 2010 4:15 pm
by requinix
Nope. You have to use getters for it.
I guess you don't trust developers to follow the rules of using your code?
Re: read only properties of an object in php4
Posted: Sat Apr 24, 2010 5:39 pm
by panic!
It's more like something like this.
I'm gonna simplify this for the sake of being concise but let's say you have a CRUD wrapper and someone by accident does something like this.
<?
$product=new product(123);
if($product->id=10){ // whoops, using assignment instead of comparison by accident?>
$product->update(); // the update function uses the id property to identify which db record it is. It now thinks it is ID 10 so we're updating 10 instead of 123 by accident.
<? } ?>
And other stuff like that which could be easily avoided by using __get and __set to abstract the variables.
Looks like I'm going to have something like <?=$product->get_property('id');?>
argghh I hate making things like this work in php4.
Re: read only properties of an object in php4
Posted: Sat Apr 24, 2010 5:43 pm
by panic!
A way I was thinking of doing it was having a private array of the real properties and values which are referred to when the class does things like updating, ignoring the properties that could be accidentally accessed and changed. Thoughts?
Re: read only properties of an object in php4
Posted: Sat Apr 24, 2010 6:10 pm
by requinix
I think that if you're going to spend this much time on trying to help other developers not make mistakes you're going to find that you have a lot less time to work on actual functionality.
Honestly, if you go through some kind of obscurity like
Code: Select all
class Foo {
var $data = array("id" => 123);
function USE_THIS_TO_MODIFY_VARIABLES($what, $value = null) {
if (in_array($what, $this->data)) {
// filtering, validation, etc...
if ($value !== null) $this->data[$what] = $value;
return $this->data[$what];
}
}
}
people will just work around it with
Code: Select all
$f = new Foo();
$f->data["id"] = "string";
You can't prevent stupid developers from being stupid. If they're modifying something as important as an ID and then trying to save it... well, that's the kind of behavior that gives programming a bad name.
Re: read only properties of an object in php4
Posted: Sat Apr 24, 2010 6:29 pm
by requinix
(a separate post)
With that said, there are ways of doing this. You can use scope and static variables to your advantage.
Code: Select all
class Foo {
var $id = 0; // integer
function Foo() {
$this->id = 123;
// call validate() once to set a key
$this->validate(md5(microtime()));
}
function validate($key = null) {
static $_key = null; // once-only key to set the $old values and types
static $old = array(); // old values (we care more about their data types)
if ($key !== null && $_key === null) {
// set the key and the old values
$_key = $key;
$old = get_class_vars("Foo");
}
$valid = true;
foreach ($old as $var => $value) {
// type mismatch
if (gettype($value) != gettype($this->$var)) {
// pick a method and remove the other
// method #1: take the existing value and type-convert it
switch (true) {
case is_int($value): $this->$var = intval($this->$var); break;
case is_string($value): $this->$var = strval($this->$var); break;
// etc.
}
$valid = false; // was invalid, now fixed
// method #2: use the old value instead
$this->$var = $value;
$valid = false; // was invalid, now reverted to the previous value
}
}
return $valid;
}
}
$f = new Foo();
echo "validate says '", ($f->validate() ? "valid" : "invalid"), "'; id="; var_dump($f->id);
$f->id = 987;
echo "validate says '", ($f->validate() ? "valid" : "invalid"), "'; id="; var_dump($f->id);
$f->id = "string";
echo "validate says '", ($f->validate() ? "valid" : "invalid"), "'; id="; var_dump($f->id);
Code: Select all
Method 1:
validate says 'valid'; id=int(123)
validate says 'valid'; id=int(987)
validate says 'invalid'; id=int(0)
Method 2:
validate says 'valid'; id=int(123)
validate says 'valid'; id=int(987)
validate says 'invalid'; id=int(123)
You'd call validate() at the very beginning of some kind of save() method.
Can build on top of this code of course: for example, always revert certain values (such as IDs).