Happy 25th birthday, PHP!

PHP 25th birthday

PHP, the language that has truly changed the web, is celebrating its 25th birthday. Over time, it gained an army of fans and army of haters, and it’s still difficult to tell which one is larger.

As someone who is using the language since its early days (yes, PHP 3), I’m glad to see that it is still around, it is still going strong, and it is still vital for the larger portions of the web.

Huge thanks go to the core development team, community, and millions of contributors and users.  It wouldn’t have been the same without you.  Happy birthday, PHP!

And here’s an awesome timeline to help you remember all the years!

 

Send additional HTTP headers to Nginx’s FastCGI

It’s not that often that I come across a useful, but undocumented feature in a major software application.  It happened recently, so I’ll document it here just for the future self.

For a particular setup, I had to send additional HTTP headers (let’s use X-GEOIP for this example) to the PHP-FPM, which was configured as a FastCGI backend in Nginx web server.  This StackOverflow thread suggested several solutions, but this one was the easiest and worked like a charm: use Nginx’s fastcgi_param directive AND prefix your variables with HTTP_.  For example:

location ~ \.php$ {
  fastcgi_param HTTP_X_GEOIP $geoip;
  ... other settings
}

 

macOS in the cloud

With the constant expansion of cloud providers and services, one would think everything is possible and easy these days.  Well, at work, we came across an interesting project which shed some light on the lesser discussed areas of cloud providers and services – macOS.

Both Linux and Windows are well suited for the cloud, and are widely covered.  macOS though not so much.  Why?  Well, there are many reasons, but one of them might be that short, but annoying paragraph in the software license agreement (this one is for Catalina, but you can easily check the others here):

J. Other Use Restrictions. The grants set forth in this License do not permit you to, and you agree not to, install, use or run the Apple Software on any non-Apple-branded computer, or to enable others to do so.You agree not to remove, obscure, or alter any proprietary notices (including trademark and copyright notices) that may be affixed to or contained within the Apple Software. Except as otherwise permitted by the terms of this License or otherwise licensed by Apple: (i) only one user may use the Apple Software at a time, and (ii) you may not make the Apple Software available over a network where it could be run or used by multiple computers at the same time. You may not rent, lease, lend, sell, redistribute or sublicense the Apple Software.

Yup.  You have to run Apple software on the Apple hardware.  This alone is a huge showstopper for the cloud.  And only user may use it at a time too.

There are still some cloud providers who offer specifically macOS based products and services (and yes, they run them on the Apple hardware).  Here are a few examples, thanks to this thread:

It’s good to have options here, even if the prices are much higher than what you’d expect.

Caddy – The Ultimate Server with Automatic HTTPS

Great things are easy to get used to.  When something works the way you want it, and does so for a long a time, it is inevitable that one day you’ll stop thinking about it altogether and accept it as a given.

Apache was a great web server, until Nginx came along.  All of a sudden, it became obvious how much faster things could be, and how much simpler the configuration file is possible.

For the last few years, Nginx was working great for me.  And now that I came across Caddy, I realized that life can be a lot simpler.

Caddy web server

Here’s a bit to get you started:

Caddy simplifies your infrastructure. It takes care of TLS certificate renewals, OCSP stapling, static file serving, reverse proxying, Kubernetes ingress, and more.

Its modular architecture means you can do more with a single, static binary that compiles for any platform.

Caddy runs great in containers because it has no dependencies—not even libc. Run Caddy practically anywhere.

Seriously? We now have a web server which handles HTTPS with automatically renewed certificates (yes, Let’s Encrypt) out of the box… Mind-blowing.  I guess, 21st century is indeed here now.

What else is there?  Well, let’s see:

  • Configurable via RESTful JSON API. OMG!  No more trickery with include files, syntax checking and restarts.  In fact, configuration files are completely optional, and even if you choose to use them, they just use the same API under the hood.  Bonus point: you can export full configuration of a running server into a file via a simple API call.
  • Extensible.  Yes, that’s right!  “Caddy can embed any Go application as a plugin, and has first-class support for plugins of plugins.”  Check out their forum for plugin-related discussions, or simply search GitHub for Caddy.
  • Supports HTTP/1.1, HTTP/2, and even HTTP/3 (ETF-standard-draft version of QUIC), WebSocket, and FastCGI.
  • … and a lot more.

Wow!  It’s definitely worth checking out.  While Nginx is not going to disappear (much like Apache being still around), Caddy might be a better option for your next project.

MySQL, JSON, indexing and generated columns

For quite some time now I wanted to play around with the recently added JSON type in MySQL.  Finally, I have a project where MySQL version is high enough to support it, and the requirements are such that this choice makes sense.

The first impression was great – JSON type is basically LONGTEXT type with a bunch of added functionality to manipulate JSON data.  It took no time to setup tables and necessary queries to work with it.

The second iteration though raised a few questions.  Large tables, with complex JSON structures were rather slow in some of the more complex queries.  The first solution to look at was obviously indexes.  Turns out, MySQL does not support indexing of the JSON fields. Bummer.

But there is a rather elegant work around.  It involves another recently added feature, of which I haven’t heard about until today – GENERATED columns.  Think of table views, but on the column level, not table level.  And generated columns can be indexed.

In fact, there’s a whole lot that you can do with GENERATED columns in general, and JSON data in particular.  This blog post – “MySQL for JSON: Generated Columns and Indexing” – provides a great starting point with examples and explanations, including a scenario with the primary key of the table being a generated column, with the data from the JSON-typed column.

Awesomeness!