Tony Marston's Blog About software development, PHP and OOP

RE: Improving PHP's Object Ergonomics

Posted on 2nd April 2020 by Tony Marston

Amended on 10th January 2021

Introduction
My responses
Value objects
Everything is an object
References
Amendment History
Comments

Introduction

Recently, while browsing the PHP internals newsgroup, I came across a discussion regarding proposed changes to the language which pointed to https://hive.blog/php/@crell/improving-php-s-object-ergonomics. Having read the article I find myself disagreeing with every point made.

Having started development in PHP as far back as 2002 after 20 years with other languages, and having developed an open source framework called RADICORE with which I has also developed a large ERP application I feel that I am qualified to discuss any so-called "failings" in the language. As none of the "problems" mentioned in the article has ever affected my style of programming I do not regard them as problems at all, and as a follower of the old engineering maxim "If it ain't broke don't fix it" if I don't have a problem then I sure as hell don't need its solution.

This article seems to be implying that there are deficiencies in the PHP language which are causing problems for some programmers, and that the language should be changed to eliminate those deficiencies. I disagree with this viewpoint entirely as I consider the real problem to be with the way that some programmers use the language - their choice of programming style - and not the language itself.

An important lesson I learned at the start of my programming career was the KISS principle which can be translated as:

A good programmer is one who writes simple code to perform complex tasks, not complex code to perform simple tasks.

If I can achieve complex tasks by writing simple code using the current features of the language then I see absolutely no benefit in making the language more complicated just to suit the personal whims of the Let's Make It More Complicated Than It Really Is Just To Prove How Clever We Are brigade.

Note that when I say "current features" I mean that although my code runs perfectly well under PHP version 7.4 I have not bothered to use any of the additional OO features that were added since PHP 4 for the simple reason that I can't find a use for them. OOP requires nothing more than support for Encapsulation, Inheritance and Polymorphism, and these were covered perfectly well in PHP 4. None of the later versions of the language have offered anything better, just different ways of doing what I have already done, or doing things that I don't need to do at all.

My Responses

The following responses are directed at the author of this article.

  1. You complain that PHP forces you to write verbose code in your constructor in order to load the object with data, but there is no rule which says that the load operation be performed ONLY in the constructor. There are other ways, better ways, so don't blame PHP for your poor choice.
  2. You complain that PHP forces you to write too much boilerplate code, but you seem to forget that the language is only supposed to provide the ability for the programmer to write human-readable code which can be transformed into machine-readable code. The language cannot decide whether code is boilerplate or not, it is just code. If you find yourself writing the same or similar pieces of code over and over again then it is YOUR responsibility to find a way to reduce that repetition. It should never be a function of the language to reduce that repetition for you or to clean up your mistakes. What it can do is provide a mechanism whereby you can define that boilerplate/common code in a single place so you can then refer to it from multiple places. You can choose from any of the following techniques:

    If any of those options is beyond your capabilities then, in my humble opinion, you should give up programming altogether as you clearly don't know how to write cost-effective software. Changing the language to deal with your deficiencies just adds useless bloat to the language, bloat that will never be used by 99% of the programming community.

  3. You complain that there is a problem with value objects (see my note below), but PHP has never supported such objects, so what is there to complain about? While it is accepted that an object must contain one or more properties and one or more methods, there has never been a rule in OOP that each property within an object must itself be an object. PHP, like so many other languages, uses primitives, not objects, so if you are saying that you cannot write cost-effective software without using value objects, then it is you who should change to a language which suits your preferences, and not PHP which should change to suit you.
  4. You complain that there is a problem with getters and setters, but again there is no rule in OOP which states that each property of an object must be declared separately, and that each of these properties must have its own pair of getters and setters. A relational database deals with datasets where each set contains any number of rows, and each row contain any number of columns, and I have found it far easier to pass this dataset around as a single argument called $fieldarray instead of having to deal with separate methods and arguments for each field with the array. In this way I achieve loose coupling which is far more desirable than tight coupling.
  5. You complain about something called the Materialized Value Object Problem, but yet again that problem is the result of your bad choice and not a fault of the language. It is possible to construct the materialised value within the SELECT query itself, which means that it then becomes just another column in $fieldarray and does not require any additional PHP code to obtain its value.
  6. You complain about something called the Documented Property problem where an object has many properties and some of those properties may be optional. Thus keeping track of which constructor argument is which can become a chore. If you choose to write code where each property has its own argument in a method call then you have to deal with the consequences of your choice. If you now realise that there are problems with the choice you made then you should choose a different option instead of trying to change the language to deal with your poor choice.
  7. You say that there is a problem with immutable objects, but PHP does not support such objects so how can they be a problem? Immutable properties and value objects were not specified in any original definitions of OO, or in any early languages which supported OO, so I regard them as optional extras which were created by someone who thought he was being clever when the result proved to be the exact opposite. I have read several discussions regarding the introduction of immutable objects into PHP, but these discussions identify a large number of complications, and there is never any agreement of how each individual complication can be solved.

Because I consider all these "problems" to be the fault of the programmer and not the language, I consider all of your proposed "solutions" which involve a change to the language to be totally unnecessary. This follows another basic principle which states Prevention is better than Cure, which means that it is far better to eliminate a disease than to mask its symptoms.

So there you have it. If your choice of programming style causes problems then you should first look into changing to a less problematic style instead of changing the language to deal with your mistakes. Remember that changing the language to suit a particular programming style may have detrimental effects on those you use a more common, simpler and less problematic style.

Value objects

Some people have challenged my statement that PHP does not support value objects. By this I mean that nowhere in the PHP manual does it mention value objects. All values, whether booleans, integers, decimals, dates or strings, are held as simple primitive data types and not value objects. The language does not provide any inbuilt value objects, nor does it provide any classes from which you can create such objects.

When you write values to your database these are provided as primitives, not objects. When you read values from your database these are provided as primitives, not objects. When you write values to your HTML output these are provided as primitives, not objects. When you read values from your HTML form by way of the $_GET or $_POST arrays these are provided as primitives, not objects.

However, there is nothing to stop any developer from creating and using their own value objects, but to me this seems like a total waste of effort. When reading data from either the database or HTML form it is presented in the form of a collection of primitive data types, so you would have to write your own code to manually move each primitive value into its equivalent object. When sending data to either to either the database or an HTML form you would then have to reverse this procedure by converting each object into its original primitive value. If data comes into and goes out of your software in the form of primitives what benefit is provided by writing additional code to convert these primitive values to and from value objects? Absolutely none! What extra functionality is provided by value objects? Absolutely none! There is no ROI (Return On Investment), so all that effort is wasted because it does not provide any benefit.

I have been told that there is a "need" for value objects when dealing with amounts in multiple currencies as the value object can store both the amount and the currency code. Absolute poppycock! I have been writing such applications for several decades in several different languages where both the amount and the currency code have been stored as separate primitives, so there has been no "need" whatsoever. HTML documents cannot deal with an object which combines both amount and currency as each requires its own separate control. Relational databases cannot deal with an object which combines both amount and currency as each requires its own column. If neither the HTML front end and the SQL back end can handle value objects then where is this "need"?

Everything is an object

OO purists often tell me that code is not "proper" OO unless it is 100% object-oriented, unless everything is an object. That is one of the reasons why they advocate the use of value objects. I hold a totally different opinion:

Everything is a string.

In the real world a value such as "42" or "dollars" is always a string, not an object, so forcing it to become an object in your code is simply forcing the use of an artificial construct. In the real world when a value is written down on a piece of paper it is always written as a string. When writing software which uses HTML at the front end and SQL at the back end every value is also a string.

If the data going into and out of your software is always in the form of a string then what is the benefit of changing a string into an object just to convert it back into a string?

References

Here are some other articles on the same topic:

The following articles describe aspects of my framework:

The following articles express my heretical views on the topic of OOP:

These are reasons why I consider some ideas on how to do OOP "properly" to be complete rubbish:

Here are my views on changes to the PHP language and Backwards Compatibility:

The following are responses to criticisms of my methods:

Here are some miscellaneous articles:


Amendment History

10 Jan 2021 Added Everything is an object
01 Sep 2020 Added Value objects

Other comments are available on this reddit post where, as usual, adult debate has given way to childish insults. You can find some of these insults here, here, here and here.

Take note of this post in which a person called zmitic claims to be able to rewrite Radicore using proper methods in just 3 weeks! This I gotta see!

counter