Ray – Dump Debugging Evolved

The folks over at Spatie have released a new tool called Ray that helps you with debugging.

Ray is a beautiful, lightweight desktop app that helps you debug your app. After installing one of the libraries to send information to Ray, you can use the ray() function to quickly dump stuff. Any variable(s) that you pass to Ray will be displayed.

Since Spatie mainly develops with Laravel it plays very nice with it. It supports logging all performed queries or properly displaying the contents of any Eloquent Model / Mailable for example.

ray('Hello world');

ray(['a' => 1, 'b' => 2])->color('red');

ray('multiple', 'arguments', 'are', 'welcome');


User::firstWhere('email', '[email protected]');

At its core Ray is “simply” an app that listens for incoming messages on a specific port (e.g. 23517). That means you can use it with any other programming language, as long as you send it the proper (JSON) payload. Libraries to use Ray with WordPress or JavaScript are already available too.

Ray →
Ray Docs →
Ray Introductory Blogpost →

💁‍♂️ Sidenote: To debug JavaScript I’d recommend the DevTools you already have though, as they’re already built for it. To debug from a remote source you could use something like JSConsole or get knee-deep in ADB and remote debugging protocols. But from a technological point of view it’s pretty cool that you can use Ray for it if you wanted to.

It’s not legacy code — it’s PHP

In 2004 Vimeo wrote their first backend code in PHP. 16 years later and they (mainly) still run PHP.

Many developers wrote a bit of PHP a decade ago and have since moved on to better-respected languages. They’re often eager to tell others how relieved they are to not be writing PHP anymore, and how it can’t be redeemed.

I’m here to tell you that it can, and Vimeo’s continued success with PHP is proof that it’s a great tool for fast-moving companies in 2020.

One can’t deny the PHP 7 release was a big leap forward. The new PHP 8 release also added quite a few nice additions to the language. Really looking forward at what’s more to come for PHP …

It’s not legacy code — it’s PHP →



Run Composer Scripts in Parallel with veewee/composer-run-parallel

Nice addition to Composer by Toon Verwerft which allows you to run your custom commands in parallel

This composer plugin allows you to run the tasks inside your composer file in parallel. No more waiting on one specific task!

Say you have these two custom commands:

  "scripts": {
    "php1": "@php -r 'sleep(3); echo \"1\";'",
    "php2": "@php -r 'echo \"2\";'"

Then you can invoke them to run in parallel as follows:

$ composer run parallel php1 php2

Using @parallel it’s also possible to trigger the functionality from inside another custom command:

  "scripts": {
    "php1And2": "@parallel php1 php2"

Installation per Composer:

$ composer require --dev veewee/composer-run-parallel

You might want to install this one globally 😉


ibis — A PHP tool that helps you write eBooks in markdown and convert to PDF

Mohamed Said recently wrote the book “Laravel Queues in Action”. To create the book he wrote it Markdown and then used his self-created tool ibis to generated the PDF and ePub versions.

Installation per Composer:

composer global require themsaid/ibis

After which you start a new project with ibis init

Check out the preview of “Laravel Queues in Action” to get an idea of what is being generated.

Laravel Queues in Action Preview (Light) →
Laravel Queues in Action Preview (Dark) →

Front Line PHP – Building modern web applications with PHP 8

The folks over at Spatie are at it again, this time with Front Line PHP.

An ebook on cutting edge tactics in PHP 8, accompanied by videos and practical examples.

The videos covering the new additions to PHP 8 are free to watch, and should give you an idea of what you can expect.

At €79 (now €56 due to #BlackFriday) this is a steal.

Front Line PHP →
Front Line PHP Videos (paid + free)

Convert Guzzle requests to curl commands with namshi/cuzzle

The other day the namshi/cuzzle PHP pacakge came in really handy.

This library let’s you dump a Guzzle request to a cURL command for debug and log purposes

This way I could test some things on the CLI, and easily share these tests with all my colleagues, including those without PHP installed.

use Namshi\Cuzzle\Formatter\CurlFormatter;
use GuzzleHttp\Message\Request;

$request = new Request('GET', 'example.local');
$options = [];

echo (new CurlFormatter())->format($request, $options);
// ~> curl example.local -X GET -A 'GuzzleHttp/6.4.1 curl/7.71.1 PHP/7.4.9'

Also comes with a Monolog formatter to easily log the resulting curl commands in your log files. Do keep in mind that you might be leaking sensitive information (passwords/tokens) that way …

Installation per Composer:

composer require namshi/cuzzle

Cuzzle, cURL command from Guzzle requests →

Parse the output of git log using PHP

This gist might come in handy one day:

Legacy to Laravel: How to Modernize an Aging PHP Application

The folks at Tighten:

In this post, I’ll present some strategies we use at Tighten to convert legacy apps to Laravel gradually over time, without needing to perform a full rewrite. Whether you’re upgrading from an old framework or moving to a framework for the first time, following these steps will let you start benefitting from all that Laravel has to offer right away.

What they basically do is set up a new Laravel project and have it catch the parts that they changed/added. Using a catchall rule, all other requests are routed to the legacy code. Clever.

Route::any('{path}', '[email protected]')->where('path', '.*');

From then on they start migrating to Eloquent models, introduce some helper functions, etc.

Legacy to Laravel: How to Modernize an Aging PHP Application →

PHP: Convert a Geolocation (Latitude / Longitude Coordinates) to a Timezone identifier

Part of a PHP project I’m working contains a list of sites/buildings. For each site/building we monitor some data, for example its energy usage.

We decided that we wanted to generate a daily/weekly/monthly reports of the data, by aggregating the datapoints. As our sites/buildings are spread across the globe – and thus timezones – we can’t simply select data between 00:00:00 UTC and 23:59:59 UTC but have to use its geographical location’s “day window” to do our calculations.

Unfortunately we don’t didn’t store the timezone for a site/building, but since we do keep track of its geographical location – using a WGS84 latitude-longitude pair – it should be possible to derive its timezone, right?

Right! On StackOverflow I found this little snippet that does the job:

function get_nearest_timezone($cur_lat, $cur_long, $country_code = '') {
    $timezone_ids = ($country_code) ? DateTimeZone::listIdentifiers(DateTimeZone::PER_COUNTRY, $country_code)
                                    : DateTimeZone::listIdentifiers();

    if($timezone_ids && is_array($timezone_ids) && isset($timezone_ids[0])) {

        $time_zone = '';
        $tz_distance = 0;

        //only one identifier?
        if (count($timezone_ids) == 1) {
            $time_zone = $timezone_ids[0];
        } else {

            foreach($timezone_ids as $timezone_id) {
                $timezone = new DateTimeZone($timezone_id);
                $location = $timezone->getLocation();
                $tz_lat   = $location['latitude'];
                $tz_long  = $location['longitude'];

                $theta    = $cur_long - $tz_long;
                $distance = (sin(deg2rad($cur_lat)) * sin(deg2rad($tz_lat))) 
                + (cos(deg2rad($cur_lat)) * cos(deg2rad($tz_lat)) * cos(deg2rad($theta)));
                $distance = acos($distance);
                $distance = abs(rad2deg($distance));
                // echo '<br />'.$timezone_id.' '.$distance; 

                if (!$time_zone || $tz_distance > $distance) {
                    $time_zone   = $timezone_id;
                    $tz_distance = $distance;

        return  $time_zone;
    return 'unknown';

Usage is as follows:

// Timezone for one NY coordinate
echo get_nearest_timezone(40.772222,-74.164581);
// ~> America/New_York

// Timezone for one Belgian coordinate
echo get_nearest_timezone(51.0162167, 3.7338451);
// ~> Europe/Brussels

// More faster and accurate if you can pass the country code 
echo get_nearest_timezone(40.772222, -74.164581, 'US');
// ~> America/New_York

With this timezone identifier now being available, we can include it in our queries and generate our daily/weekly/monthly reports 🙂

🍻 Here’s to copying-and-pasting from StackOverflow!

On a related note: Falsehoods programmers believe about time and time zones is worth a read, especially if you’ve already dealt with time and timezones.

PHP 8 in 8 Code Blocks

Brent has been following the PHP releases and featured up close. In this post he highlights 8 of the features that will make it into PHP 8

  1. Attributes (aka Annotations)
  2. Union types
  3. The static return type
  4. The just-in-time Compiler
  5. throw in Expressions
  6. Non-capturing catches
  7. Trailing commas in parameter lists
  8. New str_* functions

As a bonus he also adds the new Stringable interface and the ability to call ::class directly on objects.

PHP 8 in 8 Code Blocks →