The SitePoint Forums have moved.

You can now find them here.
This forum is now closed to new posts, but you can browse existing content.
You can find out more information about the move and how to open a new account (if necessary) here.
If you get stuck you can get support by emailing forums@sitepoint.com

If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

The whole 'why don't you think before asking?' comment was a bit harsh, to say the least. I probably could have emphasized 'more' instead of 'careful', in my earlier post, but I still don't see why people would have to be 'more' careful. Either you're careful about checking to access to undefined properties or you're not.

Originally Posted by bonefry

What are those 'good programming practices' ?

I would say having a class with all the properties defined in the class definition is a good thing.

PHP Code:

class foo {

public $bar = 1; public $baz = 2; private $zaz = 3;

}

Throwing in some phpdoc on top of that is even nicer. However, if I write my code this way, I can't deal with $bar, $baz or $zaz using the __set and __get functionality.

I'm not sure why this is being overlooked. Throwing all accesses to a missing property into one defined array is the only way I've seen it done, but it feels very much like a hack, at best.

Why do you consider __set/__get as poor programming practice ?
What does __set/__get have to do with variable initialization ?
I fail to see it.

See above.

Please provide examples, as we are talking about computer science here and not literature.

What on earth is that 'literature' reference to?

I've worked places what use E_ALL in production just to catch people who don't initialize $foo before looping an array and appending via "$foo.=$bar;". In the strictest sense, that's considered 'bad' because you didn't start by stating $foo=''; to initialize the variable. So, defining and initializing values is (apparently) considered a good thing. But you can't do that in a class definition and still have access to those properties via __get and __set functionality. Not sure what's so difficult to understand here. Apparently quite a lot of people *like* it this way, although it just seems wrong to me.

As someone else pointed out, this is fancy error handling, but it's forcing people in to creating code which would throw errors in the first place (referencing undefined properties) instead of being a more integral part of the object system which allows interception of any property access, defined or undefined.

Wow some of you can really muddy the water in what should be a very clear conversation. I deal in real world objects that need to be precise with valid data. Below is a small class used with a UPS Rates interface.

The get and set functions do just exactly what needs to be done, validate data, controll user access and are easily understood by me or another programmer using this object. I will trade off a few milliseconds for the ability to check my data any day. If you programmers are using all public varables for access to object propertys where does your data validation occur? In todays high speed server environment is erroneous data worth something undetectable to the average client?

My only complaint about variables accessed through get or set methods is that my Komodo editor does not catch them for auto completion, but is this a php problem or one with Komodos design?

I have a tendancy to create accessors in my classes due to my previous experience with Java, even though the use of private variables in PHP is limit to PHP5+. Just an old habit.

To be honest I see little difference between using accessors and not using them. Sure it's makes the code a little bit bloated but in my opinion it makes it a little more obvious as to what's happening, and maybe a little more maintainable if PHP is going down the private variable route.

Yes, I do use getters and setters within the class itself if the getter/setter does more than retrieve the variable. The whole point of using getters and setters, in my opinion, is to ensure the data you send and retrieve is safe for usage. Any security problems found with a getter/setter class are contained within one or two functions (getter and/or setter) and the vulnerability can be quickly fixed. Without the getter/setter method of working with variables, you introduce the possibility of having a single vulnerability spread throughout the entire class - which increases the work involved in patching the vulnerability and increases the chance of missing code that does need to be patched.

Using __get and __set may be okay for small objects, but I find it somewhat stupid to program that way as it is QUITE a hack. It's inviteable that you'll wind up with a large switch statement to set values and enforce domain logic in one big method. And how the heck are you supposed to generate documentation when you have no class member variables defined?

James what part of document in your class header or document in your construct function as you initalize your attributes do you not agree with? True in php all get or set methods fall into one large block of code, Maybe in php6 the zend engineers will go to a seperate set/get set of functions for each attribute as occurs in Visual Basic. The Microsoft engineers saw data validating and strict type casting as being a neccessity, something that publicly declared attributes in php seem to be lacking. While php still has some more polishing to go through the methods provided are the best we have to work with at this time. I still want to know at what point in your datas life cycle do you validate data before passing it to an object? How do you make your attributes read / write only? The language is not perfect but I have to think the great Zend engineers who have many more hours of programming time and insight had a reason for the get / set functions as they stand now.

James what part of document in your class header or document in your construct function as you initalize your attributes do you not agree with?

I think what he's meaning is that if you initialize them via 'public' or 'var' or whatever in the class, they won't get processed by the __get and __set 'magic' methods.

The language is not perfect but I have to think the great Zend engineers who have many more hours of programming time and insight had a reason for the get / set functions as they stand now.

Many more hours of programming than who? Perhaps the reason is they didn't know any better, or that they are learning as they go along. Everyone has to learn, and some people do it in public. I'm not saying PHP devs specifically DIDN'T know what they were doing, but just because it exists in the language does not mean it's correct or even good.

James what part of document in your class header or document in your construct function as you initalize your attributes do you not agree with? True in php all get or set methods fall into one large block of code, Maybe in php6 the zend engineers will go to a seperate set/get set of functions for each attribute as occurs in Visual Basic. The Microsoft engineers saw data validating and strict type casting as being a neccessity, something that publicly declared attributes in php seem to be lacking. While php still has some more polishing to go through the methods provided are the best we have to work with at this time. I still want to know at what point in your datas life cycle do you validate data before passing it to an object? How do you make your attributes read / write only? The language is not perfect but I have to think the great Zend engineers who have many more hours of programming time and insight had a reason for the get / set functions as they stand now.

The thing I do not like about them (although some may find them convenient) is that I perfer to keep my methods small and to the point. Let's say that each set method requires about 5 to 10 lines of code for some kind of domain logic. if there are 10 attributes in the class that require this, you will wind up with one big monster method with 50 to 100 lines of code.

For the most part, I use __get and __set just for handling attempts to set a public attribute that isn't declared and that shouldn't be part of the object. I know there are some who like polymorphism and "one magic object that handles variable attributes" at the center of their application, but I prefer to keep things concrete to capture the business logic.

Of course, validation doesn't occur in the data object in most instances, but rather there's other "strict" validation. If I only want DummyClass::$foo to be an object of type Foo, I'd have the appropriate setter:

PHP Code:

public function setFoo(Foo $foo)
{
$this->foo = $foo;
}

Or perhaps I don't even want to just directly set it like that. What if, as per the specifications, a variable can only be one of 10 possible values and should throw an exception on an invalid value being set (basically, an Enum)?

Regardless, we are way off course. This is not an arguement about using __set or __get, but rather, this is about using setters and getters to get/set private/protected variables and using them internally. If you are pulling that dynmanic crap and using __get and __set, the point is moot because your attributes will ALWAYS be public, and therefore I guess you don't need a setter or getter anyway.

I like where you are going with this, and I think this would really help solve the problems within a class. But what about things like DI or Persistence where you want to intercept accesses (or calls) but you won't know what the properties or methods will be. Can you just do:

public property get getAll set setAll;

There is no need for this because thats essentially __get and __set.

Although, one design decision would be whether or not to include the property name as a parameter to the accessor method. if you do, then accessor methods can be shared:

PHP Code:

public property height get $_height set setDimension;
public property width get $_width set setDimension;

On the other hand, if you include the property name as a parameter, they get slower and more complicated.

I knew it wouldn't be long before this thread got hijacked by the Ruby Enthusiasts.

I'm not hijacking, I'm not a Ruby enthusiast and neither am I joking. Ruby has proper accessors and error handling functions for "dynamic" properties. The latter we have in PHP, but crippled; last time I checked, this resulted in a fatal:

I probably could have emphasized 'more' instead of 'careful', in my earlier post, but I still don't see why people would have to be 'more' careful. Either you're careful about checking to access to undefined properties or you're not.

When I was speaking of 'more carefull', I was speaking of the extra attention you have to pay to `fixed` properties ... i.e. you have to be carefull not to throw a 'missing property' error when that property exists ... and as I tried to demonstrate ... that's an easy thing to do ... overlooking existing fixed properties.

Originally Posted by mgkimsal

I would say having a class with all the properties defined in the class definition is a good thing.

PHP Code:

class foo {

public $bar = 1;
public $baz = 2;
private $zaz = 3;

}

Throwing in some phpdoc on top of that is even nicer. However, if I write my code this way, I can't deal with $bar, $baz or $zaz using the __set and __get functionality.

I'm not sure why this is being overlooked. Throwing all accesses to a missing property into one defined array is the only way I've seen it done, but it feels very much like a hack, at best.

My friend, you are talking about only one way to handle this.
Keeping undefined properties in an array is not the only way to go.

As I demonstrated earlier, you can use __set/__get + reflection to build a C#-like setter/getter system.

Because someone complained it is slow (I'm too lazy to search for that message now) I will give a more simple sollution which doesn't use the complex and slow reflection framework in PHP5:

I appreciate the fuller example you just gave. If it works for you, that's great. That seems a bit convoluted, as you seem to have to make your properties private, and you would seem to lose the distinction between private and public properties.

Anyway, as I said, if this works for you and you are productive with this, that's fine.

Nothing that I can see. At this point the question becomes do I want to add those __get and __set methods in every class (or in a base class) so I can access properties like this, $object->property, instead of this, $object->getProperty(). The answer for me is no.

And this really should be in a standard library somewhere so we can extend from it:

The problem is (as someone already mentioned) that __get/__set are not reenterable, which IMO makes the whole feature pretty useless. In fact, arrow notation for 'virtual' properties is simply dangerous, because this will fail miserably if gets into __get execution chain.

The problem is (as someone already mentioned) that __get/__set are not reenterable, which IMO makes the whole feature pretty useless. In fact, arrow notation for 'virtual' properties is simply dangerous, because this will fail miserably if gets into __get execution chain.

This gets back to the Container thread. Because of the quirks in __get/__set, the design that currently can do everything PHP4 and PHP5 is:

PHP Code:

class Keyed {
function get($key)
function set($key, $value)
}

You can: set an existing property, create a non-existent property, error on a non-existent property, store values in some other var such as an array, or call a "get$key()" method. You just can't do $obj->key = $value;

Could this be a version related issue? They fixed chaining virtuals ($a->b->c, where b and c are virtual) in 5.0.5, and I've no reason to believe your example wouldn't work; I believe I've done it in several occasions.