Paul M. JonesQuality: Program vs Product (26.9.2017, 12:00 UTC)


Why it is that programmers and their employers have different attitudes toward the quality of a project? Thinking of myself as a programmer, I have sometimes formulated it like this:

  • The programmers who do the work are usually the ones who care more about “quality.” Why?

    • They have a reputation to maintain. Low quality for their kind of work is bad for reputation among their peers. (Note that their peers are not necessarily their employers.)

    • They understand they may be working on the same project later; higher quality means easier work later, although at the expense of (harder? more?) work now.

  • The employers who are paying for the work care much less about “quality.” Why?

    • The reputation of the payer is not dependent on how the work is done, only that the work is done, and in a way that can be presented to customers. Note that the customers are mostly not the programmer’s peers.

    • They have a desire to pay as little as possible in return for as much as possible. “Quality” generally is more costly (both in time and in finances) in earlier stages, when resources are generally lowest or least certain to be forthcoming.

    • As a corollary, since the people paying for the work are not doing the work, it is easier to dismiss concerns about “quality”. Resources conserved earlier (both in time and money) means greater resources available later.

These points are summed up well by Redditor JamesTheHaxor, who says: “Truth is, nobody cares except for us passionate programmers. We can judge a persons skill level based on their code quality. Most clients can’t. They judge a persons skill level by how fast they can get something done for the cheapest price that works to spec. There’s plenty of shoddy coders to fill that market. They always undercut me on freelance sites.”


The problem is that the term “quality” means different things to different people. The in the programmer/employer situation, there are two different definitions of “quality” at play (or two different things that are being paid attention to).

  • The programmer’s “quality” relates to the what he sees and works with regularly and is responsible for over time (i.e., the code itself: the “program”).

  • The employer’s “quality” relates to what he and the customers see and work with regularly and are responsible for over time (i.e., what is produced by running the code: the “product”).

“Quality of program” is not the same thing as “quality of product.” They have different impacts at different times in the project, and have different levels of visibility to different people involved in the project. They do not exist independently of each other, and feed back on each other; change one kind of quality, and the other kind will likewise change.

I think this disconnect also applies to various non-software crafts and trades. You hear about carpenters, plumbers, painters, etc. complaining that they get undercut on prices by low-cost labor who don’t have the same level of quality. And yet the customers who choose the lower-cost option are satisfied with the quality level, given their resource constraints. The programmer-craftsman laments the low quality of the work, but the payer-customer just wants something fixed quickly at a low cost.

Dismissing quality concerns of either kind early on may cause breaks and stoppage when the product is more visible or closer to deadline, thus leading to greater stress and strain to get work done under increasing public scrutiny. The programmer blames the lack of code quality for the troubles, and the employer laments the programmer’s inability to work as quickly as he did earlier in the project.

What’s interesting to me is that the programmer has some idea about the product quality (he has to use the product in some fashion while building it), but the manager/employer/payer has almost no idea about the code quality (they are probably not writing any code). So it’s probably up to the programmer to understand the consequences of program quality in terms of product quality.

Qafoo - PHPChecklist For A Reliable Load-Test (26.9.2017, 08:09 UTC)
Setting up a load-test that produces results you can rely on is not that simple. But without realistic test-results you cannot be sure that your application handles sudden increases of traffic, rapid spikes or even the initial go-live. And you cannot estimate at which number of users you should scale up your hardware. Both details are very important to keep the application running at all times and guarantee that no revenue or developer sleep is lost because of outages. We have a large checklist of points we go through when setting up performance tests with customers and I wanted to discuss some of the more important points in this blog post.
Voices of the ElePHPantInterview with Brandon Savage (25.9.2017, 11:30 UTC)

Show Notes

The post Interview with Brandon Savage appeared first on Voices of the ElePHPant.

SitePoint PHPLet’s Compare: RunCloud vs Forge vs ServerPilot (24.9.2017, 13:20 UTC)

When your website or web application has outgrown your shared hosting account, it is time to move it to the cloud, or into a virtual private server (VPS). Nowadays, VPS providers offer better value in terms of CPU and RAM resources than the shared hosting counterparts. However, I can recall when I wanted to move my website to Amazon Web Services a few years ago, and it took me days to deploy the server and get it ready with PHP, MySQL and Apache.

Fortunately, that is not the case today as we have the help of some cool tools and third party services.

I took a look at three similar services - RunCloud, ServerPilot and Laravel Forge - and compared them to see which performs best. These are SaaS tools that can help deploy, configure, manage, and monitor VPS on any cloud hosting providers like AWS, Linode, Vultr, Digital Ocean, and others.


Registration was easy. You don't need a credit card and you can even use your Facebook, Google, or GitHub account. If you don't fancy using your social media account, then just use your email address.

With RunCloud, what you need to do is deploy a fresh Ubuntu 16.04 LTS VPS on almost any VPS hosting provider. Throughout this tutorial I used a Linode VPS which costs $5 per month.

When your server is ready, you go back to RunCloud and enter your server details like the IP address to get your connection command.

Connecting a Server on RunCloud

You will get a very long one-line command like this.

Command for RunCloud

All that you need to do is run the command in your server as the root user and let it run. It will probably take about 15 to 20 minutes for the process to complete, and once you are done, you can start to manage your server from within the web panel.

Managing Your Server

Next you need to create a Web Application. That is like a virtual host in the web server. When you do that, you can select your PHP version, and you can assign your domain name to the Web Application. You can assign more than one.

The UI is very user friendly and intuitive and you can find whatever you need rather quickly and easily. My most basic need would be to be able to create virtual hosts (Web Application), assign domain names and create databases and perhaps deploy my application from GitHub or any other Git server. There is also a script installer that supports WordPress, Joomla, Concrete5, PHPMyAdmin and a few more common PHP tools.

If you do PHP development and use Git, RunCloud supports deploying your script from GitHub, Bitbucket, Gitlab and also your own custom Git server installation.

A server overview

Managing a web application

We'll look into performance later.


ServerPilot is probably the oldest among the three, and most well-marketed. When I ask around if anybody is using a server management tool, it will probably be has a Free account that you can use with limited features, and there are also the Coach ($10/mo) and Business ($49/mo) plans. Please bear in mind, these prices are for server deployments and not per account to ServerPilot.

Coach has more features like free SSL via LetsEncrypt, server health stats and other. The Business package is more like a mini NewRelic or an application performance monitoring service. You can see slow script request, application resources stats and more.

Of course the Free package is good enough, but limited compared to their Coach and Business options.

Connecting A Server

This feels similar to RunCloud. You also need a fresh Ubuntu 16.04 VPS server to start. If you have the root password to your server, you don't need to copy and paste the installer command via SSH. You can enter your server IP address and your root password, and ServerPilot will get your server ready in a few minutes.

However, if you don't want to enter the root password of your server into ServerPilot, then you can opt not to do that. You can get i

Truncated by Planet PHP, read more at the original (another 5024 bytes)

Voices of the ElePHPantInterview with Megan Lalk (22.9.2017, 11:30 UTC) Link
Nomad PHPImplementing Serverless PHP (22.9.2017, 04:01 UTC)

December - EU
Presented By

Rob Allen
December 21, 2017
20:00 CET

The post Implementing Serverless PHP appeared first on Nomad PHP.

Voices of the ElePHPantInterview with Ed Barnard (21.9.2017, 11:30 UTC) Link
Voices of the ElePHPantInterview with Mark Story (20.9.2017, 11:30 UTC) Link
Rob AllenCORS and OpenWhisk web actions (20.9.2017, 10:03 UTC)

By default, OpenWhisk will handle the relevant responses for CORS.

Specifically, it will respond to an OPTION request with these headers:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: OPTIONS, GET, DELETE, POST, PUT, HEAD, PATCH
Access-Control-Allow-Headers: Authorization, Content-Type

If you need to change what is sent or you don't want to send these headers at all, then you need to do set the annotation web-custom-options to true and handle the OPTIONS header yourself.

Note that if you don't set this annotation, you must not set any of these headers yourself as you'll break things!

Implementing the CORS headers yourself

To implement the CORS headers yourself you do something like this in your action (example in Swift, PHP version at the end):

func main(args: [String:Any]) -> [String:Any] {

        let corsAllowedOrigin = "" // URI that may access this resource ("*" is wildcard)

    // OPTIONS handling for CORS
        let method = args["__ow_method"] as? String,
        let headers = args["__ow_headers"] as? [String:Any]
    else {
        return ["statusCode": 500]
    if method == "options" {
        let allowedHeaders = headers["access-control-request-headers"] ?? "Content-Type, Authorization"
        return [
            "statusCode": 200,
            "headers": [
                "Access-Control-Allow-Methods": "OPTIONS, GET, PUT, DELETE",
                "Access-Control-Allow-Origin": corsAllowedOrigin,
                "Access-Control-Allow-Headers": allowedHeaders

    let data = ["hello": "world"]

    return [
        "statusCode": 200,
        "headers": [
             "Content-Type": "application/json",
             "Access-Control-Allow-Origin": corsAllowedOrigin, // don't forget this header!
        "body": Data(WhiskJsonUtils.dictionaryToJsonString(jsonDict: data)!.utf8).base64EncodedString()

Create it it OpenWhisk with:

wsk action create api api.swift --web true -a web-custom-options true

For a "non-simple" request, the browser will send an OPTIONS request to the option that you need to respond to. This is call the "preflight" request.

The __ow_method in args will tell you the method (lowercased) and __ow_headers will contain all the headers that were sent.

If the method is options, then we need to return the CORS headers. You can expect that the client will send a Access-Control-Request-Headers header containing the list of headers that its going to send to you when it does the actual request. If you don't have a white list of headers that you're expecting, then you should send back the list you are sent as otherwise the request will fail.

You also need to set the Access-Control-Allow-Methods header to the list the methods you accept for this end point; it is the CORS version of the Allow header. The client should send you a Access-Control-Request-Method header to tell you the method it will use when it sends the actual request.

If the method is not OPTIONS, then you send back your response as usual. In addition, you need to send the Access-Control-Allow-Origin header with the same value as you used for the preflight request.

That's it.

Aside: PHP version

As an aside, here's how it looks in PHP, where the type handling looser:


function main(array $args) : array
    $corsAllowedOrigin = ""; // URI that may access this resource ("*" is wildcard)

    // OPTIONS handling for CORS
    $method = $args["__ow_method"] ?? "";
    $headers = $args["__ow_headers"] ?? [];
    if ($method == "options") {
        $allowedHeaders = $headers["access-control-request-headers"] ?? "Content-Type, Authorization";
        return [
            "statusCode" => 200,
            "headers" => [
                "Access-Control-Allow-Methods" => "OPTIONS, GET, PUT, DELETE",
                "Access-Control-Allow-Origin" => $corsAllowedOrigin,
                "Access-Control-Allow-Headers" => $allowedHeaders

    $data = ["hello" => "world"];

    return [
        "statusCode" => 200,
        "headers" => [
             "Content-Type" => "application/json",
             "Access-Control-Allow-Origin" => $corsAllowedOrigin, // don't forget this header!
        "body" => base64_encode(json_encode($data))

The PHP version operates in the same manner as the Swift one, so the discussion above applies to this code too. The most obvious differences are the lack of a guard section do handle the type & optional casting from the args dictionary and the ease of converting an array to a base64 string in PHP.

Paul M. Jones“Before” (not “Beyond”) Design Patterns (19.9.2017, 12:00 UTC)

(N.b.: This has been languishing at the bottom of my blog heap for years; time to get it into the sun.)

The 2013 article Beyond Design Patterns takes the approach of reducing all design patterns to a single pattern: “Abstracting Communication Between ‘Components’.” The author concludes, in part:

Instead of focusing on design patterns, I would suggest focusing on understanding how communication between objects and components happens. How does an object “decide” what to do? How does it communicate that intention to other objects.

Are design patterns useful? Absolutely. But I’ll assert that once you understand OOP and object communication, the patterns will “fall out” of the code you write. They come from writing OOP.

This strikes me as misapplied reduction. Sure, it’s true that, at a lower level or scope, it might be fair to say that “the pattern is ‘communication.’” But it is also true that, at a somewhat higher level or scope, communication between “which things” in “what way” is also fair. So the article might better be titled not “Beyond Design Patterns” but “Beneath Design Patterns” or “Before Design Patterns”. The concepts illustrated are not consequences of or improvements on design patterns; they are priors to design patterns.

The analogy that came to my mind was one of molecules and atoms. An imaginary article on chemistry titled “Beyond Molecules” might thus conclude …

Instead of focusing on molecules, I would suggest focusing on understanding how interaction between atoms happens. How does an atom “decide” what to do? How does it communicate that intention to other atoms?

Are molecules useful? Absolutely. But I’ll assert that once you understand atoms and atomic interaction, the molecules will “fall out” of the formulas you write.

… which is true enough for as far as it goes, but it is also revealed as a rather superficial and mundane observation when presented this way. Atoms are not “beyond” molecules.

So: molecules are a proper unit of understanding at their level or scope. Likewise, design patterns are a proper unit of understanding at their own level. Reducing them further does not show you anything “beyond” – it only shows you “because.”

LinksRSS 0.92   RDF 1.
Atom Feed   100% Popoon
PHP5 powered   PEAR
ButtonsPlanet PHP   Planet PHP
Planet PHP