My PHP is rusty to nonexistent at best, but if I understand the code correctly, these "getters" are in fact some Frankensteinian getter/setter combinations. Use without an argument, and you get the current value of the class variable, use with an argument to set. Which is funny, but not particularly useful, and might just be more confusing in the long run, when someone besides the original dev maintains that code.
From what I understand, if the functions are called without argument, the interpreter defaults to using null, which causes the 'if($license)' to fail and just return the value of the static variable. However, PHP plays it very fast and loose with what it considers true or false. Basically, according to (http://stackoverflow.com/questions/6693876/how-exactly-does-ifvariable-work), pretty much anything besides boolean false, empty arrays or strings, and (presumably) null is treated as true. So, if a parameter is passed, 'if($license)' evaluates to true, and assigns the passed value to the static variable before returning said value.
Addendum to the above: If you pass a false-y value (meaning, any variant of 0 (string, float, int...), boolean false, an empty list or string, etc.), the program will silently ignore that assignment, and the next get will still return the same value.
This has been a supported pattern in AngularJs for model binding for a while now, too. Its pretty useful when the model you're binding to must be manipulated via input controls in a way that doesn't correspond 1:1 with some property on the model. It also lets you avoid using the usually-overkill ng-model formatters/parsers stuff
If the methods here were just named properly (e.g. getSet* instead of get*), it wouldn't really be a WTF
The real problem is that these getterSetter Frankenstein monsters are class instance functions that modify static variables.
Using this in an OOP context is not really defined in the manual (and I never tried something that weird), but I guess that those are shared between object instances.
You would be right, but look closer at the variable names. You pass in a value, assign it to a local variable and return that local variable. The static members are basically untouched (since they're named the same as the incoming parameter).
I've had to work on a system that used the getterSetter pattern frequently, and to be honest when done correctly isn't terrible. I would rather have specific get and set methods, but sometimes it's more difficult to have/support that pattern.
I think folks are missing the line about "masking". The instance variables are never used inside the functions because the parameters being passed in have the same name, and thus mask the member variables in scope.
I figured that since there are both parameter variables and class variables sharing the same names, that the parameter variables would be used inside the function. Yet another little PHP gotcha, or at least something that looks that way to me.
The public properties are never used. There is no masking as there is no implicit $this in PHP. The static variables are shared among all instances. The code is horrible, no doubt, but TRWTF is not knowing enough about the language and code to properly criticize them.
The member variables are never used in the methods. Not because of masking, but because of PHP.
Unlike other languages, member variables must explicitly use $this->[name] so the methods purely use the static variables, meaning that if you use both the (public) member variables and the get-setter methods, you will experience different results.
Also - as some others have noted - you cannot UNset a value, since that will be interpreted as getting.
Remy's premise in the original article about ERP software is incorrect, probably because nobody remembers the LEO lesson about what we'd call ERP today.
Paraphrased, it says that projects to computerise the operations of a company are doomed to fail. Instead, the project must first change the operations to be easily (or even trivially) computerised while keeping them manual, and then computerising the new operations (which are, in essence, computerised operations conducted manually by humans).
The key advantage of this approach is that you can quietly drag Old Fred round the back of the bike shed and put a bullet through his thick skull, so that Old Fred's Report(1) will not trouble the computer, and you can do this before there are any computers involved in running the company, so the demise of OFR will not (directly) be blamed on the computers ("what computers? there are no computers here").
(1) I've talked about this before, on this very site. I won't bother you by rehashing it.
So in the context of modern ERP systems: these systems are, by definition, primarily used by people trying to computerise the boundless variety of "manual" ERP procedures without first reining in the boundlessness of that variety. The ERP systems, therefore, must be sufficiently flexible to deal with that variety, and that returns us to the question of accommodating OFR and similar abominations, and that leads us to customisation hooks and Inner Platforms and the like. Converting the operations to be computerised has the result of reducing that variety of procedures, thus imposing a much lower customisation load on the ERP software.
This is basically the same as what jQuery does. If you pass an argument to height, it sets the height, and if you don't, it just gets the value (see this article https://martinfowler.com/bliki/OverloadedGetterSetter.html). Except that in this case it's worse, because the "getters/setters" are explicitly named "get".
Let me see if I have this straight. If you call getLicensee with a parameter, such as the one passed from the constructor, which in turn is the one passed to the constructor, it sets the static variable "id" to that value (as long as it's "truthy" - such a godawful concept). If you call getLicensee without a parameter, it returns whatever is in the static variable "id". So the getter/setter method is sort of working, in that you can get or set the value "id", and it is set by the constructor using the passed parameter.
Except the actual member field "licensee" is never read from or set to anything by this method, and is presumably set to null (although I wouldn't want to make any assumptions about PHP). And it has public access. And if that is assigned anywhere, it won't be used by the getter/setter method. OK, that's just awful.
Based on HorusKol's comment, I'm assuming a static variable is static to the method, but not to each instance? CBF checking out that link - learning about PHP has negative value to me.
Yeah, they managed to take one of Perl's worse ideas (those guys love their xetters, not that there's a lack of features that may have seemed useful to Larry 40 years ago but not today) and run with it.
Remy's "Law" is broken. While it is true in many (most) cases it cannot be considered a law since a sufficiently small audience or a strictly regulated context regardless of size of audience may reduce complexity and thus lead to high quality software.
Funny , the bash on PHP. It is just a tool, folks.
And like a knife, you can slice your bread with it, kill the president with it or cut your own throat. In this example, it is more of the latter though.
I've seen things in other languages where I wondered if the programmer had learned programming without even opening a book or following a course.
You can have an opinion on PHP and OO. I have the same on e.g. java-versioning hell. Or the Java copy-action from Microsoft called CLR. Every concept in both languages is 'borrowed' from Objective C by the way.
In my opinion, you have the combination of programmer(s) and language. If the first sucks, the language doesn't matter. You'll get rubbish anyway. If you have good programmers, the language or platform isn't very interesting. You can do equivalent things in most languages anyway.