Pragmatism in the real world

Changelog generator for GitHub milestones

For many years now, I've been using Matthew Weier O'Phinney's changelog_generator script to generate an easy-to-read list of changes for a given milestone. Time has moved on; the Laminas project now uses Laminas Automatic Releases and Matthew hasn't updated his script since 2013. Since PHP 8, warnings have started appear, so it's clear updates were required. While I fully intend to see if I can use Automatic Releases on some projects, I have others where… continue reading.

Setting HTTP status code based on Exception in Slim 4

One thing that's quite convenient is to be able to throw an exception with a valid HTTP code set and have that code sent to the client. For example, you may have: throw new \RuntimeException("Not Found", 404); With the standard Slim 4 error handler, this response is sent to the client: $ curl -i -H "Accept:application/json" http://localhost:8888 HTTP/1.1 500 Internal Server Error Host: localhost:8888 Content-type: application/json { "message": "Slim Application Error" } Ideally we want… continue reading.

Dependency injection in Serverless PHP with Bref

When writing PHP for AWS Lambda, Bref is the way to do it. One thing I like about Bref is that you can use PSR-15 Request Handlers to respond to API Gateway HTTP events as documented in the API Gateway HTTP events section of the Bref docs. The request handler is the same as used in PSR-7 micro-frameworks like Slim or Mezzio and can be thought of as a controller action. As such, it's really… continue reading.

Installing PHP extensions without pecl in PHP 8 Docker images

UPDATE: Since this was published, PR 1087 has been raised and merged with restores pecl to the Docker PHP 8 images. I discovered recently that pecl is no longer shipped in the PHP Docker images for PHP 8. This appears to be related to the deprecation of –with-pear in PHP core as noted in issue 1029. Consider this Dockerfile: FROM php:8.0.0RC5-cli-buster RUN pecl install mongodb && docker-php-ext-enable mongodb If you build, you'll discover the pecl… continue reading.

Step-debugging linked composer dependencies with PhpStorm

One project I'm working on has multiple separate parts in different git repositories that are brought into the main project using linked composer directories. I needed to get step debugging working in PhpStorm and this is the approach I took.

Recursive PHP lint

There are many scripts that recursively execute php -l on a set of files or directories. This is mine: #!/usr/bin/env bash set -o nounset # Recursively call `php -l` over the specified directories/files if [ -z "$1" ] ; then printf 'Usage: %s …\n' "$(basename "$0")" exit 1 fi ERROR=false SAVEIFS=$IFS IFS=$'\n' while test $# -gt 0; do CURRENT=${1%/} shift if [ ! -f $CURRENT ] && [ ! -d $CURRENT ] ; then echo… continue reading.

Validating default PHP session ID values

I recently needed to validate the value created by PHP for its session ID. After a bit of research, I realised that there are two interesting php.ini config settings that relate to this value: session.sid_length is the number of characters in the ID session.sid_bits_per_character controls the set of characters used. From the manual: The possible values are '4' (0-9, a-f), '5' (0-9, a-v), and '6' (0-9, a-z, A-Z, "-", ","). Therefore, to validate the session… continue reading.

Routing in Slim 4

Routing in Slim 4 works pretty much exactly the same as in Slim 3. They are used to map a URL that the browser requests to a specific handler that executes the code for that particular page or API endpoint. You can also attach middleware that will only be run when that route is matched. The route in the slim4-starter looks like this: $app->get('/[{name}]', HomePageHandler::class); It is made up of the method, the pattern and… continue reading.

Changing an SQL Server primary key in Doctrine Migrations

I recently came across a rather weird quirk when trying to change a primary key in Sql Server using Doctrine Migrations: you need to use two migrations to get it to work. This is incredibly minor and I'm only writing it up as it confused me for a while so I thought that I'd document so that I'll find this article if I run across it again in the future! This is the migration: final… continue reading.