Paul M. Jones

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

Conserving On The Wrong Resource

(This is a blog post I’ve had in a "write-me!" folder for years; I am now publishing it in its unfinished form to get it off my mind.)

Programmers are acutely aware of their limited resources: CPU, memory, storage, requests-per-second, screen space, line length, and so on. If programmers are aware of a resource constraint, they conserve on it; sometimes they call this “optimizing.”

Are you aware of a loop? Then you try to “optimize” it, or conserve on it, e.g. by not using a count() in the loop declaration.

Are you aware of the number of lines? You might try to conserve on the number of lines, perhaps by removing blank lines (especially in docblocks).

Are you aware of aware of the size of an array, or the number of objects in the system, and so on? You try to conserve on those, to reduce their number.

But this is sometimes a trap, because you conserve or optimize on a low value
resource you are aware of, at the cost of not conserving on a high-value resource you are not aware of. For example, optimizing a for loop by not using count() in its declaration will have little impact if the loop is executing queries against an SQL database.

Lesson: conserve on high-value resources that you may not be aware of, not low-value ones that are obvious but of little consequence.


What the "Anti-Federalists" Got Right

First, the Anti-Federalists predicted that the federal government the Constitution created would increase its power until states were merely secondary considerations. Second, that this powerful federal government would be too big and distant for the people to effectively control, and thus vainglorious men of ambition and avarice would control it to enrich themselves off the common people.Third, that it was unwise to govern a diverse and large population from a remote and distant government that would hold such immense power over the daily lives of common people, and, as a result, politics would become something more primitive than civilized, characterized by constant discord and fighting as different factions tried to control the lives of their fellow citizens.

Source: The Anti-Federalists Predicted Today’s Political Morass, & Can Get Us Out


Faster Evolution Means More Ethnic Differences

Russian scientists showed in the 1990s that a strong selection pressure (picking out and breeding only the tamest fox pups in each generation) created what was -- in behavior as well as body -- essentially a new species in just 30 generations. That would correspond to about 750 years for humans. Humans may never have experienced such a strong selection pressure for such a long period, but they surely experienced many weaker selection pressures that lasted far longer, and for which some heritable personality traits were more adaptive than others. It stands to reason that local populations (not continent-wide "races") adapted to local circumstances by a process known as "co-evolution" in which genes and cultural elements change over time and mutually influence each other.

Source: Edge.org


The PHP 7 "Request" Extension

tl;dr: The new request extension provides server-side request and response objects for PHP 7. Use it as a replacement object for request superglobals and response functions. An equivalent PHP 5 version is available in userland as pmjones/request.


You're tired of dealing with the $_GET, $_POST, etc. superglobals in your PHP 7 application. You wish $_FILES was easer to deal with. You'd prefer to wrap them all in an object to pass around to your class methods, so they'd be easier to test. And as long as they're all in an object, it might be nice to have parsed representations of the various incoming headers. Preferably, you'd like for it to be read-only, so that the various libraries you use can't modify superglobal state out from under you.

Likewise, seeing the “Cannot modify header information - headers already sent” warning is getting on your nerves. You'd like to get away from using header(), setcookie(), and the rest. You know they're hard to inspect, and they're hard to test. What would be great is to have all that response work wrapped in another object that you can pass around, and inspect or modify it before sending the response back to the client.

You could maybe adopt a framework, but why do that for your custom project? Just a pair of server-side request and response objects would make your life so much easer. Why can't there be set of internal PHP classes for that?

Well, now there is. You can install the request extension from John Boehr and myself to get ServerRequest and ServerReponse objects as if PHP itself provided them.

ServerRequest

After you install the extension, you can issue $request = new ServerRequest(), and then:

Instead of ...                          ... use:
--------------------------------------- ---------------------------------------
$_COOKIE                                $request->cookie
$_ENV                                   $request->env
$_GET                                   $request->get
$_FILES                                 $request->files
$_POST                                  $request->post
$_SERVER                                $request->server
$_SERVER['REQUEST_METHOD']              $request->method
$_SERVER['HTTP_HEADER_NAME']            $request->headers['header-name']
file_get_contents('php://input')        $request->content
$_SERVER['HTTP_CONTENT_LENGTH']         $request->contentLength
$_SERVER['HTTP_CONTENT_MD5']            $request->contentMd5
$_SERVER['PHP_AUTH_PW']                 $request->authPw
$_SERVER['PHP_AUTH_TYPE']               $request->authType
$_SERVER['PHP_AUTH_USER']               $request->authUser

Likewise:

Instead of parsing ...                  ... use:
--------------------------------------- ---------------------------------------
isset($_SERVER['key'])                  $request->server['key'] ?? 'default'
  ? $_SERVER['key']                     (good for all superglobals)
  : 'default';
$_FILES to look more like $_POST        $request->uploads
$_SERVER['HTTP_CONTENT_TYPE']           $request->contentType and
                                        $request->contentCharset
$_SERVER['HTTP_ACCEPT']                 $request->accept
$_SERVER['HTTP_ACCEPT_CHARSET']         $request->acceptCharset
$_SERVER['HTTP_ACCEPT_ENCODING']        $request->acceptEncoding
$_SERVER['HTTP_ACCEPT_LANGUAGE']        $request->acceptLanguage
$_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] $request->method
$_SERVER['PHP_AUTH_DIGEST']             $request->authDigest
$_SERVER['HTTP_X_REQUESTED_WITH']       $request->xhr
  == 'XmlHttpRequest'

Those properties are all read-only, so there's no chance of them being changed without you knowing. (There are some true immutables for application-related values as well; see the documentation.)

ServerResponse

For responses, you can issue $response = new ServerResponse(), and then:

Instead of ...                          ... use:
--------------------------------------- ---------------------------------------
header('Foo: bar', true);               $response->setHeader('Foo', 'bar');
header('Foo: bar', false);              $response->addHeader('Foo', 'bar');
setcookie('foo', 'bar');                $response->setCookie('foo', 'bar');
setrawcookie('foo', 'bar');             $response->setRawCookie('foo', 'bar');
echo $content;                          $response->setContent($content);

You can inspect the $response object, and then call $response->send() to
send it to the client.

Working with JSON?

// instead of ...
header('Content-Type: application/json')
echo json_encode($value);

// .. use:
$response->setContentJson($value);

Sending a $file for download?

// instead of ...
header('Content-Type: application/octet-stream');
header('Content-Transfer-Encoding: binary');
header(
    'Content-Disposition: attachment;filename="'
    . rawurlencode(basename($file)) . '"'
);
$fh = fopen($file, 'rb+');
fpasthru($fh);

// use:
$fh = fopen($file, 'rb+');
$response->setContentDownload($fh, basename($file));

Building a complex header? Pass an array instead of a string:

$response->setHeader('Cache-Control', [
    'public',
    'max-age' => '123',
    's-maxage' => '456',
    'no-cache',
]); // Cache-Control: public, max-age=123, s-maxage=456, no-cache

$response->setHeader('X-Whatever', [
    'foo',
    'bar' => [
        'baz' => 'dib',
        'zim',
        'gir' => 'irk',
    ],
    'qux' => 'quux',
]); // X-Whatever: foo, bar;baz=dib;zim;gir=irk, qux=quux

Find Out More

You can read the rest of the documentation at https://gitlab.com/pmjones/ext-request to discover more convenient functionality. And if you're stuck on PHP 5.x for now, the extension has a userland version installable via Composer as pmjones/request.

Try out the request extension today, because a pair of server-side request and response objects will make your life a lot easier.


The Conflict of Desirable Values

The central values by which most men have lived, in a great many lands at a great many times--these values, almost if not entirely universal, are not always harmonious with each other. Some are, some are not. Men have always craved for liberty, security, equality, happiness, justice, knowledge, and so on. But complete liberty is not compatible with complete equality--if men were wholly free, the wolves would be free to eat the sheep. Perfect equality means that human liberties must be restrained so that the ablest and the most gifted are not permitted to advance beyond those who would inevitably lose if there were competition. Security, and indeed freedoms, cannot be preserved if freedom to subvert them is permitted. Indeed, not everyone seeks security or peace, otherwise some would not have sought glory in battle or in dangerous sports.

Justice has always been a human ideal, but it is not fully compatible with mercy. Creative imagination and spontaneity, splendid in themselves, cannot be fully reconciled with the need for planning, organization, careful and responsible calculation. Knowledge, the pursuit of truth--the noblest of aims--cannot be fully reconciled with the happiness or the freedom that men desire, for even if I know that I have some incurable disease this will not make me happier or freer. I must always choose: between peace and excitement, or knowledge and blissful ignorance.

Source: A Message to the 21st Century | by Isaiah Berlin | The New York Review of Books


Definition of "Done"  in a web project

- Source code meets our coding standards.

- High enough level of unit test coverage for routes, action methods and controllers.

- High enough level of unit test coverage for business logic and repositories.

- High enough level of automated UI and integration test coverage.

- Code has been peer reviewed.

- Code must be completely checked in to the source control system and the build and all the automated tests should be green.

- UI looks nice and works on different resolutions on major browsers and browser editions.

- UI fulfills the accessibility requirements.

- UI works with and without javascript enabled.

- End user help/documentation/tooltips are done.

- Any auditing/tracing code is added and the output is useful and readable.

- Security permission checks have been implemented and validated via automated tests.

- Automated database migration scripts are provided and testedSample data needed to test the feature is scripted, if required.

- Users have tested the feature and are happy with it.

I'll nitpick and note that "MVC" is not an application architecture, but whatever. Source: Definition of Done in an MVC project


Cursing as "Competence" Signal

My days, nobody cursed in public except for gang members and those who wanted to signal that they were not slaves: traders cursed like sailors and I have kept the habit of strategic foul language, used only outside of my writings and family life. Those who use foul language on social networks (such as Twitter) are sending an expensive signal that they are free – and, ironically, competent. You don’t signal competence if you don’t take risks for it – there are few such low risk strategies. So cursing today

(A counterpoint to the previous post.) Source: How To Legally Own Another Person – Medium


The Case for Manners

I think that codes of manners also can be used to convey respect for others. You are telling people, including strangers, that you conduct yourself with them in mind.

I believe that restraint in the use of four-letter words used to serve this purpose, and it could once again serve this purpose. This puts me at odds with my fellow Baby Boomers and those who came after.

Source: The Case for Manners | askblog


MY SIDE vs YOUR SIDE

All of MY SIDE's references and statements are to be taken in the coolest, hip-ironic, culturally aware, benign-metaphorical way possible; all of YOUR SIDE's references and statements are to be taken in the most mindlessly literal, threatening way possible.

Any charge against MY SIDE requires exquisite legally admissible proof of its accuracy; WHEREAS, any charge against YOUR SIDE must be true if it was asserted by anyone, anywhere.

People on MY SIDE are responsible only for what they said personally, in full-quotation context; BUT, people on YOUR SIDE are responsible for the inferred implications of anything said by anyone who ever held any idea vaguely similar to what your people think.

(Edited for brevity and flow.) Source: THE NEW REFORM CLUB: Judge Boggs


Avoiding Quasi-Immutable Objects in PHP

tl;dr: Immutability in PHP is most practical when the object properties are scalars or nulls. Using streams, objects, or arrays as properties makes it very difficult, sometimes impossible, to preserve immutablity.


One of the tactics in Domain Driven Design is to use Value Objects. A Value Object has no identifier attached to it; only the combination of the values of its properties gives it any identification. If you change any of the properties in any way, the modification must return an entirely new instance of the Value Object.

This kind of behavior means the Value Object is “immutable.” That is, the particular instance is not allowed to change, though you can get back a new instance with modified values. The code for an immutable object looks something like this:

<?php
class ImmutableFoo
{
    protected $bar;

    public function __construct($bar)
    {
        $this->bar = $bar;
    }

    public function getBar()
    {
        return $this->bar;
    }

    public function withBar($newBar)
    {
        $clone = clone $this;
        $clone->bar = $newBar;
        return $clone;
    }
}
?>

(Note how $bar is accessible only through a method, not as a public property.)

When you create an ImmutableFoo instance, you cannot change the value of $bar after instantiation. Instead, you can only get back a new instance with the new value of $bar by calling withBar():

<?php
$foo = new ImmutableFoo('a');
$newFoo = $foo->withBar('b');

echo $foo->getBar(); // 'a'
echo $newFoo->getBar(); // 'b'
var_dump($foo === $newFoo); // (bool) false
?>

With this approach, you are guaranteed that one place in the code cannot change the $foo object at a distance from any other place in the code. Anything that ever gets that instance of $foo knows that its properties will always be the same no matter what.

The immutability approach can be powerful in Domain Driven Design and elsewhere. It works very easily in PHP with scalar values and nulls. That’s because PHP returns those by copy, not by reference.

However, enforcing immutability in PHP is difficult when the immutable object properties are non-scalar (i.e., when they are streams, objects, or arrays). With non-scalars, your object might seem immutable at first, but mutablity reveals itself later. These objects will be “quasi-“, not truly, immutable.

Streams as Immutable Properties

If a stream or similar resource has been opened in a writable (or appendable) mode, and is used as an immutable property, it should be obvious that object immutability is not preserved. For example:

<?php
file_put_contents('/tmp/bar.txt', 'baz');

$foo = new ImmutableFoo(fopen('/tmp/bar.txt', 'w+'));
$bar = $foo->getBar();
fpassthru($bar); // 'baz'

rewind($bar);
fwrite($bar, 'dib');
rewind($bar);

fpassthru($foo->getBar()); // 'dib'
?>

As you can see, the effective property value has changed, meaning immutability has been compromised.

One way around this might be to make sure that immutable objects themselves check that stream resources are always-and-only in read-only mode. However, even that is not a certain solution, because the resource pointer might be moved by reading operations in different parts of the application code. In turn, that means reading from the stream may yield different results at different times, making the value appear mutable.

As such, it appears that only “read-only” streams can be used as immutable properties, and then only if the immutable object restores the stream, its pointers, and all of its meta-data to their initial state every time the stream is accessed.

Objects as Immutable Properties

Because PHP returns objects as references, rather than as copies, using an object as a property value compromises the immutability of the parent object. For example:

$foo = new ImmutableFoo((object) ['baz' => 'dib']);
$bar = $foo->getBar();
echo $bar->baz; // 'dib'

$bar->baz = 'zim';
echo $foo->getBar()->baz; // 'zim'

As you can see, the value of $bar has changed in the $foo instance. Any other code using $foo will see those changes as well. This means immutability has not been preserved.

One way around this is to make sure that all objects used as immutable properties are themselves immutable.

Another way around this is to make sure that getter methods clone any object properties they return. However, it will have to be a recursively deep clone, covering all of the cloned object’s properties (and all of their properties, etc.). That’s to make sure that all object properties down the line are also cloned; otherwise, immutability is again compromised at some point.

Arrays as Immutable Properties

Unlike objects, PHP returns arrays as copies by default. However, if an immutable object property is an array, mutable objects in that array compromise the parent object’s immutability. For example:

$foo = new ImmutableFoo([
    0 => (object) ['baz' => 'dib'],
]);

$bar = $foo->getBar();
echo $bar[0]->baz;

$bar[0]->baz = 'zim';
echo $foo->getBar()[0]->baz; // 'zim'

Because the array holds an object, and because PHP returns objects by reference, the contents of the array have now changed. That means $foo has effectively changed as well. Again, immutability has not been preserved.

Likewise, if the array holds a reference to a stream resource, we see the problems described about streams above.

The only way around this is for the immutable object to recursively scan through array properties to make sure that they contain only immutable values. This is probably not practical in most situations, which means that arrays are probably not suitable as immutable values.

Settable Undefined Public Properties

Finally, PHP allows you to set values on undefined properties, as if they were public. This means it is possible to add mutable properties to an immutable object:

$foo = new ImmutableFoo('bar');

// there is no $zim property, so PHP
// creates it as if it were public

$foo->zim = 'gir';
echo $foo->zim; // 'gir'

$foo->zim = 'irk';
echo $foo->zim; // 'irk'

Immutability of the object is once again compromised. The only way around this is to impelement __set() to prevent setting of undefined properties.

Further, it might be wise to implement __unset() to warn that properties cannot be unset.

Conclusion

If you want to build a truly immutable object in PHP, it appears the best approach is the following:

  • Default to using only scalars and nulls as properties.
  • Avoid streams as properties; if a property must be a stream, make sure that it is read-only, and that its state is restored each time it is used.
  • Avoid objects as properties; if a property must be an object, make sure that object is itself immutable.
  • Especially avoid arrays as properties; use only with extreme caution and care.
  • Implement __set() to disallow setting of undefined properties.
  • Possibly implement __unset() to warn that the object is immutable.

Overall, it seems like immutability is easiest with only scalars and nulls. Anything else, and you have a lot more opportunity for error.

Remember, though, there’s nothing wrong with fully- or partially-mutable objects, as long as they are advertised as such. What you want to avoid are quasi-immutable objects: ones that advertise, but do not deliver, true immutability.

(For some further reading, check out At What Point Do Immutable Classes Become A Burden?)

Update 1:

Update 2:

UPDATE 3: Beware Leaking Mutability.