Paul M. Jones

Don't listen to the crowd, they say "jump."

Speaking at Bulgaria PHP 2019

I mentioned a couple of days ago that, as favors to friends, I am temporarily relaxing my self-imposed restriction on speaking at conferences I have to fly to. The first was EEConf 2019; the second is Bulgaria PHP.

As the opening talk of day 2, I'll be giving a brand-new presentation on "Rethinking What You Think You Know." It's nominally about the road to Action Domain Responder, but I expect to include more than just that. See you there!

Don’t Believe All Women, Because Some Are Terrible

"Maybe we should treat people like people:"

[I]if we are required to believe every woman who makes an accusation, then every allegation, simply by the act of making it, becomes “credible.” This leaves little room for raising questions about honesty and due process, and plenty of space for ideological distortion.

And since ideology abhors nuance, simple narratives come to dominate the discussion when an allegation is made (in Kavanaugh’s case: beer-drinking private school boy = bad; beer-drinking private school girl = good). And anything that contradicts the narrative is explained away or ignored (such as, being drunk is damning evidence if you’re the accused man, but exculpatory if you’re the woman who made the allegation).


Speaking at EEConf 2019

I have been lax in pointing out that I will be speaking at EEConf 2019 in October. Here's a preview of the topic, and some other background:

I have for some years now sworn off speaking at conferences that I have to fly to. I hate air travel, not only because of the experience itself but because I often get sick, and once brought illness home to my family. But in this case (and in one other to be mentioned later!) I am making an allowance as a favor for a friend.

See you at EEConf!

Knitting Has Always Been Political

This is a couple of months old, but it echoes the totalitarian SJW attitudes in software as well:

Ravelry, a popular website for knitters and crocheters, took a political stand when it announced that it was banning content that supports President Trump, in what it said was a resolution against white supremacy.

“We cannot provide a space that is inclusive of all and also allow support for open white supremacy,” the site said in a statement explaining the decision. “Support of the Trump administration is undeniably support for white supremacy.”

The policy applies to content on the site, including knitting patterns and forum posts, but not to people, according to Ravelry, which said it still welcomed Republicans and those with conservative political views. “You can still participate if you do in fact support the administration, you just can’t talk about it here,” the statement said, adding that “hate groups and intolerance are different from other types of political positions.”

To the SJW, the totality of everything is political. There is no non-political space. All your hobbies and interests must be held hostage to social justice.

Via NYTimes with Twitter commentary here.

Farewell, Wendy

Wendy Lou Jones, aged around 17, passed away this morning. She was good when she was not being naughty. Clever, resilient, thiefy little dog. :-)




Moving Away From Google

In an effort to extract Google's tentacles from my life, and to give them as little feedstock as possible, I am no longer using my Gmail account as a primary contact address. Contact me at my address instead. Likewise, my address is no longer being hosted by Google.

It was surprisingly time-consuming to find a reasonable alternative host that would support some other functionality (more on that later). After some preliminary attempts, I settled on Namecheap. Believe it or not, I am using a shared hosting plan, which supports another effort I am trying out (more on that in another post).

Immutable Objects for PHP

The new immutablephp/immutable package provides truly immutable value objects and an immutable value bag, along with base Immutable and ValueObject classes for your own objects. It helps to prevent against the oversights described by my earlier article Avoiding Quasi-Immutable Objects in PHP. (Of course, it cannot prevent you from deliberately adding your own mutable behaviors, or from using reflection to mutate an object from the outside. If you do those things, you get what you deserve.)

Its base Immutable class protects against common oversights in PHP regarding immutables:

  • It defines final public function __set() and final public function __unset() to prevent adding and mutating undefined properties.

  • It defines final public function offsetSet() and final public function offsetUnset() to prevent adding and mutating values via ArrayAccess.

  • It prevents multiple calls to __construct() to re-initialize the object properties.

Further, the base ValueObject class with() method checks the types of all incoming values to make sure they are themselves immutable. It does so via static methods on the Type class.

The Type class recognizes scalars and nulls as immutable. All other non-object values (such are resources and arrays) are rejected as mutable.

When it comes to objects, the Type class recognizes anything descended from Immutable as immutable, as well as DateTimeImmutable. To allow Type to recognize other immutable classes, call Type::register() with a variadic list of fully-qualified class names that you want to treat as immutable.

After installing immutablephp/immutable via Composer, you can use it to create your own immutable Value Objects, or consume one of the provided Value Objects:

There is also an immutable value Bag for an arbitrary collection of immutable values; it can be useful for immutable representations of JSON data.

If you need truly immutable objects for your PHP project, give immutablephp/immutable a try!

Read the Reddit commentary on this post here.

Clarifications to a review of Action Domain Responder

Herberto Graça, as part of his Software Architecture Chronicles, saw fit to review the Action-Domain-Responder pattern that I have written so much about. It’s a good writeup, and you should read the whole thing, but it is off in a couple of places. I sent Herberto a followup email with some minor corrections and clarifications; I repeat it below (with light editing) for posterity.

The ADR pattern was created by Paul M. Jones

I prefer to say, not that I “created” the pattern, but that I “recognized and named” it in 2014. Slim, for example, already had single-action controllers at that time, and the various Domain Logic patterns previously existed as well. If I “created” anything, it was the idea of the Responder; that is, of treating the Response-building work as a completely separate concern. But even that is just an application of Separated Presentation.

to adjust MVC to the context of web REST APIs.

APIs were one aspect, but the origin was more in the typical HTML page-based interface. For example, the word “Action” in Action Domain Responder was inspired both by “action” methods in Controllers, and by the “action” attribute on <form> tags in HTML interfaces.

because the idea is to adapt the MVC pattern to the context of an HTTP REST API, the Action (Controller) names are mapped to the HTTP request methods so we will have Actions with names as Get, Post, Put, Delete

Well, you can do that, but it’s not strictly necessary. I think it would be more accurate to say that it’s typical for an Action to be mapped to a route, and for the routes themselves to be mapped to GET/POST/PUT/DELETE etc.

As an organization pattern, all Actions on a resource should be grouped under a folder named after the resource.

That is one reasonable approach, but it’s not dictated by ADR. Alternatively, instead of grouping Actions by resource, you might organize them by Use Case, or by the intended Interactions with the underlying application.

This pattern was thought of specifically for REST APIs, so in this form it is not refined enough to be used in web applications with an HTML interface (ie. what would be the name of the action to show a form, prior to creating a resource?) … I think the pattern can easily be extended so that it is fully usable with an HTML interface: We can emulate some extra HTTP methods specifically to handle the HTML requests that a REST API does not have.

Given my notes above, I think it’s fair to say that new HTTP methods are not really needed. What is needed, as Herberto already points out, is a way to “show a form prior to creating a resource” (among other things).

Because the Actions do not necessarily map one-to-one with HTTP methods, it’s easy enough to specify that GET /{$resource}/new (or something similar) routes to an Action that gets default values for that resource from the Domain, then hands off to a Responder that builds the form HTML. You can see an example of that here:

You might route the first as GET /blog/new and the second as POST /blog. (That idea appears to originate from Ruby on Rails and has been imitated elsewhere.)

Aside from those notes, Herberto’s article is a fair summary and description of ADR. I’m glad he put it together.

You can read more about Action Domain Responder at

Open Source and Squeegee Men

It is the Christmas season, and Christmas is a time for giving gifts: to family, to friends, and to colleagues. Some even give gifts to strangers they may never meet, as an expression of charity or of generosity, or in thankfulness for their own abundance.


When someone receives a gift, they do well to return something to the giver … but the return is not primarily a material one. The recipient does the right thing to compensate the giver, not first with money or merchandise, but most importantly with gratitude and good will.


I think open source software is little like the giving and receiving of gifts.

Read the rest at