read only properties of an object in php4

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
panic!
Forum Regular
Posts: 516
Joined: Mon Jul 31, 2006 7:59 am
Location: Brighton, UK

read only properties of an object in php4

Post 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?
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: read only properties of an object in php4

Post 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?
User avatar
panic!
Forum Regular
Posts: 516
Joined: Mon Jul 31, 2006 7:59 am
Location: Brighton, UK

Re: read only properties of an object in php4

Post 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.
User avatar
panic!
Forum Regular
Posts: 516
Joined: Mon Jul 31, 2006 7:59 am
Location: Brighton, UK

Re: read only properties of an object in php4

Post 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?
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: read only properties of an object in php4

Post 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.
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: read only properties of an object in php4

Post 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).
Post Reply