About Blog Avatar Social Contact
Development

I just need a little help

30 November 2024 - 5 min

When starting a new project, there are always a bunch of useful global helpers that I add to assist in development (and to reduce the number of keystrokes required to get the job done). Here are some of my favorites...


1. user()

We frequently need to access the authenticated user, so instead of writing auth()->user() every time, I shorten it to just user().

An added bonus is that you can specify a return type for the function, so you get much better intellisense within your IDE:

use App\Models\User;
use Illuminate\Support\Facades\Auth;

/**
 * Retrieve the currently-authenticated user.
 *
 */
function user() : ?User
{
    return Auth::user();
}

2. arr()

Laravel has a nice set of array functions, as does PHP, however it can feel awkward trying to remember whether to reach for Arr::* or array_*, so I put them behind a unified interface.

The function will opt for Laravel's array functions first, and then fall back to PHP if the function isn't available:

use Illuminate\Support\Arr;

/**
 * Retrieve an instance of the array helper class.
 *
 * @return \Illuminate\Support\Arr|mixed
 */
function arr() : mixed
{
    return new class () {
        public function __call($method, $parameters)
        {
            if (method_exists(Arr::class, $method)) {
                return Arr::$method(...$parameters);
            }

            return "array_{$method}"(...$parameters);
        }
    };
}

3. download()

While you can use file_get_contents() to retrieve a file on the internet, it isn't something that you really want to reach for in production.

This is due to it not handling connection timeouts and general timeouts. It also doesn't support retries, nor can you fake the request. So instead of using it, I use Laravel's HTTP client instead:

use Illuminate\Support\Facades\Http;

/**
 * Retrieve the file at the given url.
 *
 */
function download(string $url) : string
{
    return Http::timeout(app()->isProduction() ? 10 : 0)
        ->connectTimeout(app()->isProduction() ? 5 : 0)
        ->retry(app()->isProduction() ? 10 : 0, 5000, null, false)
        ->get($url)
        ->throw()
        ->body();
}

4. primitive()

Working with PHP's basic types e.g. strings and integers, are fine when you need to persist or send their values. However, these days we also deal with more complex data types such as enums and objects.

I wrote this function to extract the primitive value of these data types, which I then use for actions, such as comparing equality:

/**
 * Extract the given value's most primitive form.
 *
 */
function primitive(mixed $value) : mixed
{
    if ($value instanceof BackedEnum) {
        return $value->value;
    }

    if ($value instanceof UnitEnum) {
        return $value->value;
    }

    if (is_object($value)) {
        return (string) $value;
    }

    return $value;
}