On deprecating dynamic properties

Yesterday the RFC regarding Deprecating Dynamic Properties went into voting phase and it currently looks like the overwhelming majority supports the RFC.

But nevertheless the discussions yesterday started in the wider PHP community whether that is a good idea or not.

To summarize the RFC in very short terms: Currently PHP allows to assign values to a class property that was not previously declared. The RFC proposes to remove this implicit feature in PHP9. It will still be available as an explicit feature when the creator of the class adds an Annotation [AllowDynamicProperties] on the class level.

To prepare for that, in the next minor version of PHP – PHP 8.2 – whenever one assigns a value to an undeclared property there will be a deprecation notice raised.

So the proposal is – in essence – about moving from implicitness to explicitness. Which is in my opinion a very good move.

So what is the discussion that I was talking about previously all about? After all that sounds like a good move, doesn’t it?

In essence I have so far heard three different arguments against this that I want to address here. Should I have missed an argument, feel free to drop me a line in the comments of via email or twitter.

The change is unnecessary

One of the arguments is that the change is not really necessary. Why do we have to change the language for no reason?

While that is indeed a good question, that question can be applied to almost every change that needs to be done. That sounds a bit like “back in the old days…”.

But it indeed raises a good question: What are the advantages of the change? Are there any advantages on the underlying C-Code? Does internals suddenly have to support 25% less C-code due to that change? (Hint: It doesn’t look like that. The PR to implement the feature contains mostly added lines) Or is that one step ahead on a big roadmap that we all agreed upon towards a common goal? (Hint: No it isn’t. Or at least I have no knowledge about a detailed written down Roadmap of the PHP-language)

So in essence the main reasoning for the change is that someone proposed a change to the language to make it more explicit. And to reduce mistakes that can happen due to typos with the current implicit approach. While that seems like a small and perhaps unreasonable change, it is in my opinion a good approach towards that more explicitness. And, also my opinion, it fixes something that should never have worked in the first place.

This though is in my opinion the best question and the one I have not yet really gotten an answer to.

The code changes puts too much burden onto maintainers

The arguments tend to go into the direction of “due to that change, maintainers have to do a lot of additional work because they have to touch a lot of files”.

Yes! A lot of code needs to be prepared for this change. Espechially when the implicit behaviour was used as a feature. And this will become even more challenging for maintainers of code that needs to support versions of PHP before PHP8 as that needs actual code changes and not just adding an annotation.

Though the great thing is, that there are from now on at least two years of time to tackle the modifications. And afterwards the code will be much more explicit in terms of property assignment.

Why 2 years? End of this year we will see the general availability of PHP8.1 and – according to the PHP timeline – one year later we will see PHP8.2 which will introduce raising the deprecation notice. And then at least another year until PHP9. And I doubt that we will see PHP9 immediately after PHP8.2. So there might be an additional one or two years. But that we can not be sure of.

So two years to replace implicit assignments with explicit assignments. By i.e. replacing this code

$this->$prop = $value;

with this

// The magic __set and __get methods are not affected by this change!

Yes there is change necessary. But two years sound like a reasonable timeframe to tackle that change now that we know about it. And when PHP8.2 comes out we will also have the added help of the deprecation notice to help with that.

And while that sounds like I don’t care about the added burden for the maintainers, it shows something else. People like to use libraries free of charge but they do not like to help support those libraries. Instead of giving back and preparing a PR for necessary changes they add additional burden on the maintainers by abusing them for “not fixing their shit”. More on that attitude in the next chapter.

And the other thing that shows is that espechially the maintainers that were very vokal about their added burden tend to support not only the PHP-versions that are currently supported by internals (PHP7.4 and PHP8.0 at the time of writing. PHP7.3 only receives security updates for a further month). Some of them support code that still supports PHP down to version 5.3!

While that is a great movement for the users of that code, it now brings us into the situation that the language PHP can not advance in version 9 because some people want to be able to receive maintenance for code running on PHP5.3. We are talking about 12 years! So again users that are not able or not willing to update to a recent PHP version expect to get the latest version of someone elses code.

That sounds like we as maintainers need to free ourselves!

Users will flood issue-trackes with false positives

This is in essence the third argument that I often heard. Maintainers time will be taken up because users will raise issues, because the maintained code suddenly causes entries in the error log. Must be an error therefore!

Educating users seems to be impossible. Users aren’t capable of reading manuals or docs and they are equally incapable of setting up servers properly (deprecation messages are nothing to log on a production system) or distinguishing between an error, a notice or a deprecation information.

But that is what we need to reach! The point, where people can distinguish that. Whether that is by educating people or by automatically closing issues that contain the word “deprecation” is a different question.

But the main thing here is, that the stupidity of people at the end of the process hinder development. Or should I say the fear of the stupidity of people?

In the end no matter what RFC will be proposed, it will change someones workflow. By trying to make it well for everyone will not be able to make anything. It somehow reminds me of this XKCD (there’s always one)

Should that be a reason to not go on with developing PHP to a more explicit language while still keeping old behaviours? Not in my opinion.

But how can we reduce the burden on maintainers then?

Some of the burden they will have to remove themselves. Sorry to say so, but the language can not solve political issues. And whether your maintained code needs to support old and unsupported versions of PHP is something that you will have to answer for yourself. That can for example mean that new features will not be delivered to users running outdated PHP versions. Where “outdated” in this case is defined by you, not PHP internals. But you as a maintainer can decide whether you want to provide new features to people still running PHP5.3. Or PHP5.6 or even PHP7.3.

On the other hand there are things that internals actually could do. One idea would be to, by default, not provide users with messages that they can’t do anything about in the first place. Why should people see a message about the usage of some deprecated feature inside a library they are using when they can’t do anything about it? That is not of interest to the user. Only to the maintainer.

So why can we not ignore all errors that are raised in code within one or more declarable folders? By default that could be the folder vendor but users could be able to configure that via ini-settings (and therefore also via ini_set in a bootstrapping file of a widely used application to adapt that behaviour.

Something like log_ignore_folders. Not sure how to declare folders from there. Via relative or the projects root-folder or absolute but perhaps that could be discussed in a separate RFC targeting PHP8.2.

The advantage would be that users will not see deprecation messages that they can then report to the maintainers.

Would making the feature opt-in before making it opt-out help? To be honest: I doubt it. Because at one point it will become opt-out. And that usually is the pain point. And at least I am one of those people that have enough on their plate that i will tackle an issue when it becomes necessary. Which in that case will be when it becomes opt-in. And I guess that a lot of the maintainers are similar. So making the feature opt-in in the first place and later opt-out will only move the issue to somewhere in the future.

All in all I think the feature is the right way.

But perhaps one of the things that is missing is that clear perspective, where we all want the language to evolve into. What is the roadmap.

And in this case one of the huge drawbacks of PHP is the way in which the language is developed. Internals is a rather heterogenous group of people. There is no clear lead. Issues are worked on depending on who has time and knowledge on the topic. But that is a – while related – different topic that can’t solve the direct issues we are talking about here.

Any other thoughts?