Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

The Lost Functions Laravel Package

jawira/the-lost-functions

Jawira's The Lost Functions is a lightweight PHP utility library that fills gaps in the standard library with simple, dependency-free helpers for common array, string, and value operations. Drop-in functions for cleaner, more expressive PHP code, with namespaced, reusable helpers designed for modern...

View on GitHub
Deep Wiki
Context7

Getting Started

composer require jawira/the-lost-functions

There is nothing to wire up: no service provider, no facade, no config file to publish, no migrations. The package registers a Composer autoload.files entry, so its functions are available everywhere the Composer autoloader is loaded — Artisan commands, queued jobs, seeders, Blade, config/*.php, and plain PHP scripts in bin/.

Three things to do before you write code:

  1. Read the README index first. The package is a grab-bag grouped by category (arrays, strings, filesystem, type conversion/formatting). Skim the whole list once — the value is in knowing what exists so you don't hand-roll it later.
  2. Check the actual signatures, not the docs. vendor/jawira/the-lost-functions/src/ is small; open it and confirm argument order, return types, and whether a function is a polyfill (global namespace, guarded by function_exists) or a namespaced helper.
  3. Confirm what Laravel already gives you. Laravel 11's Illuminate\Support\Number::fileSize(), Str::contains(), Arr::get() with dot notation, and Carbon's diffForHumans() overlap with several of these functions. The package earns its place where you want a plain function rather than an Illuminate\Support dependency.

A good first use case is an Artisan command that reports storage or timing, where the output is for humans and you don't want to pull in a formatter:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use function jawira\TheLostFunctions\bytes_to_string;

class StorageReport extends Command
{
    protected $signature = 'storage:report';

    public function handle(): int
    {
        $bytes = (int) shell_exec('du -sb storage/app 2>/dev/null');

        $this->line('storage/app: ' . bytes_to_string($bytes));

        return self::SUCCESS;
    }
}

Verify the autoload picked it up before debugging anything else:

php -r "require 'vendor/autoload.php'; var_dump(function_exists('jawira\\TheLostFunctions\\bytes_to_string'));"
# or
php artisan tinker --execute="dump(bytes_to_string(1048576));"

If that returns false, run composer dump-autoload — the files entry is only registered when Composer regenerates the autoloader.

Implementation Patterns

Always import with use function. Every function lives in the jawira\TheLostFunctions namespace. Importing at the top of the class gives you IDE completion, greppability, and a compile-time-ish failure if the package is ever removed:

use function jawira\TheLostFunctions\array_first;
use function jawira\TheLostFunctions\bytes_to_string;
use function jawira\TheLostFunctions\time_to_string;

Formatting boundary. The most defensible day-to-day use is presentation-layer formatting: file sizes in an admin dashboard, durations in a job/queue report, booleans rendered as true/false in an API debug payload. Keep these calls at the edge (commands, controllers, Blade, log context), not in domain services — nothing here is business logic.

Log::info('import finished', [
    'rows'      => $rows,
    'duration'  => time_to_string($seconds),
    'peak_mem'  => bytes_to_string(memory_get_peak_usage(true)),
]);

Use it outside the Illuminate boundary. The strongest argument for this package over Laravel helpers is code that intentionally does not depend on illuminate/support: a shared internal Composer package, a standalone script, a config/*.php file computing a derived default, or a migration/seeder that must run in a bare php context. There, Arr::get() isn't available and a namespaced function is exactly right.

Wrap it in one place. Because these are plain functions, they cannot be mocked or faked like a facade. For anything you'll test around, put a thin adapter in app/Support/:

namespace App\Support;

use function jawira\TheLostFunctions\bytes_to_string as lostBytesToString;

final class Format
{
    public static function bytes(int $bytes): string
    {
        return lostBytesToString($bytes);
    }
}

You get one place to swap implementations (or vendor the function later) and a mockable seam in tests via a container binding if you need it.

Blade. Namespaced functions must be fully qualified or aliased into the view. Prefer a directive or a view composer over inline FQCNs:

// AppServiceProvider::boot()
Blade::directive('bytes', fn (string $expr) => "<?php echo e(\\jawira\\TheLostFunctions\\bytes_to_string($expr)); ?>");
<p>{{ $file->name }} — @bytes($file->size)</p>

Pick one convention per project. Don't let Str::contains(), str_contains(), and a lost-functions equivalent coexist in the same codebase. Inside an app, lean on Laravel's helpers for arrays and strings and reserve this package for the conversion/formatting helpers Laravel genuinely lacks or where you need framework-free code. Document the rule in the repo so the next developer doesn't re-litigate it in every PR.

Pin and audit it like a dependency. Add it to composer.json with a caret constraint, keep it out of require-dev, and review it on PHP upgrades — a package whose purpose is backfilling missing functions is by definition at risk of being superseded by the language.

Gotchas and Tips

Missing use function is the #1 error. Inside a namespaced class, an unqualified bytes_to_string() first resolves to App\Console\Commands\bytes_to_string, then falls back to the global namespace — which the package does not populate. You get Call to undefined function App\...\bytes_to_string(). Add the import; don't "fix" it with a leading backslash.

Watch for collisions with polyfills and legacy helpers. Some of these are conceptually identical to functions shipped by symfony/polyfill-* or to global helpers that older Laravel versions and legacy packages defined (array_get, str_contains, str_starts_with). The namespacing mostly saves you, but if any function is a global-namespace polyfill guarded by function_exists(), load order determines which implementation wins. If you see unexpected behavior, dump function_exists('<fqfn>') and check the autoload order.

Check for a native or framework equivalent first. On Laravel 11 / PHP 8.1+, a large slice of this library is redundant: Number::fileSize(), Number::abbreviate(), Str::contains(), Str::limit(), Arr::first(), Arr::get(), Carbon::diffForHumans(). Adding a dependency to get bytes_to_string when Number::fileSize($bytes, precision: 2) exists is a net loss. Justify each addition.

It won't show up in static analysis for free. PHPStan/Psalm need to see the function definitions; the package ships no stubs as far as I can tell. Add vendor/jawira/the-lost-functions/src to scanFiles (PHPStan) or the equivalent, or you'll get "Function not found" errors that don't reflect reality. PhpStorm resolves use function fine once the autoloader is generated — re-run composer dump-autoload after install if it shows red.

Restart long-lived workers. Under Laravel Octane, RoadRunner, or Swoole, Composer files autoload runs once at worker boot. After composer require or an upgrade, php artisan octane:reload (or restart the workers) — otherwise stale workers won't have the functions and you'll get confusing intermittent undefined function errors that vanish on a fresh php artisan serve.

Don't leak it into a package's public API. If you publish a Laravel package, do not type-hint or return values produced by a third-party function in a way that forces consumers to install it. Convert at the boundary (return (string) $formatted;) or vendor the one function you need under your own namespace.

Vendor the three functions you actually use if you're risk-averse. This library has zero dependents and a single maintainer, and its whole premise is filling gaps the language has since closed. If your usage is two or three helpers, copying them into app/Support/helpers.php (respecting the license — check LICENSE in vendor/) removes an unmaintained dependency and the autoload cost. For a broader surface area, keep the package and pin it exactly.

Autoload files costs you a small, unconditional include on every request. It's negligible, but it is not lazy like PSR-4 — this is another reason not to reach for it when Illuminate\Support\Str already solves the problem.

Debugging checklist when a function "doesn't exist":

  1. composer show jawira/the-lost-functions — is it actually installed?
  2. grep -r "the-lost-functions" vendor/composer/autoload_files.php — is the file registration present?
  3. composer dump-autoload after any composer.json edit.
  4. Confirm the exact namespace and function name from vendor/jawira/the-lost-functions/src/ — a typo in the FQCN produces the same "undefined function" error as a missing install.
  5. Under Octane: restart workers.

Extension points are effectively none. It's a flat set of functions, not a configurable component — there's no config to publish, no manager class to extend, no container binding to override. Treat it as you would a polyfill: consume it, wrap it where you need a seam, and expect to outgrow parts of it with each PHP and Laravel release.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin