jbzoo/utils
JBZoo Utils is a practical, framework-agnostic collection of PHP helpers for arrays, strings, files, CSV, XML, JSON, URLs, and more. It provides consistent APIs and reusable, well-tested tools that reduce boilerplate and speed up everyday PHP and Laravel development.
Install with Composer:
composer require jbzoo/utils
There is no service provider, no facade, no config file, and nothing to publish. The package is a flat set of static-method classes under the JBZoo\Utils namespace. Your first stop should be the src/ directory (or the class index in the README) to see what's available: Arr, Str, Vars, Filter, FS, Cli, Dates, Colors, Url, Email, IP, Sys, Ser, Http, CSV, Img, Xml, Json, Obj, Num, Env.
The fastest first use case is anything that Laravel doesn't cover well or where you're outside a normal Laravel request lifecycle (a queue worker, a standalone package, a CLI script, a migration). For example:
use JBZoo\Utils\Arr;
// Deep get with a default, works on arrays or objects
$value = Arr::get($payload, 'data.user.profile.name', 'anonymous');
// Set a nested value, creating intermediate keys
Arr::set($config, 'services.mailgun.domain', 'mg.example.com');
A second good entry point is Str::slug() for non-Latin/transliterated slugs, or Vars::bool() / Vars::int() for normalizing loosely-typed form or API input before it hits your validation layer.
Treat it as a grab-bag, not a framework. Import classes individually (use JBZoo\Utils\Str;) rather than reaching for a facade. It composes cleanly with Laravel collections:
$flat = collect(\JBZoo\Utils\Arr::flatten($nested))->filter()->unique()->values();
Wrap static helpers in a small injectable service. Because everything is static, mocking in tests is awkward. A one-line adapter class per concern (e.g. App\Support\Slugger delegating to Str::slug) keeps your code testable and gives you a single swap point if the package changes.
Deep config merging. Arr::get/Arr::set/Arr::unset handle dot notation and are useful when merging package defaults with user config, especially in a package service provider where you don't want to depend on Illuminate\Support\Arr for an unbounded set of keys.
Input normalization in FormRequests. Use Vars::bool, Vars::int, Vars::float, and Vars::string for explicit casting before validation, and Filter::* (email, url, ip) when you want a different rule set than Laravel's filter_var-backed validators. Normalize with Email::normalize() for lowercase-domain and trim rules before storing.
Theme/color work. Colors (hex ↔ rgb ↔ hsl) is genuinely useful for generating hover states, dark-mode variants, or CSS variable palettes. This is one of the few areas Laravel has no opinion on.
Artisan commands. Cli::exec() accepts arrays and handles escaping, which is safer than string-building with shell_exec. Combine with FS::* helpers for safe reads/writes and temporary directories inside commands. Keep Cli output calls out of web requests — they're CLI-SAPI oriented.
Environment and system introspection. Env::get(), Sys::*, and Ser::* are handy in diagnostic commands (php artisan app:diagnose) and health-check endpoints, but see gotchas below.
Name collisions are the number-one footgun. JBZoo\Utils\Str and JBZoo\Utils\Arr will collide with Illuminate\Support\Str and Illuminate\Support\Arr in the same file. Alias them:
use JBZoo\Utils\Str as JBStr;
use JBZoo\Utils\Arr as JBArr;
Env::get() is not Laravel's env(). It reads getenv() / $_ENV directly and does its own parsing. When Laravel's config is cached, environment variables may not be present the same way, and env() returns null after the first boot cycle. Inside Laravel, prefer config() in application code and reserve Env::get() for config files or standalone scripts.
Return false instead of throwing. Many FS::* helpers (and some Http::* helpers) return false on failure rather than raising. Always check the return value; don't assume a chain of FS::mkdir → FS::write succeeded.
Truthiness differs from filter_var. Vars::bool() has its own truthy/falsy table, which is stricter and slightly different from FILTER_VALIDATE_BOOLEAN. Read the source before relying on it for feature flags or API booleans — especially for values like '0', 'off', and ''.
Don't assume Str::random() is crypto-safe. The charset and generation strategy differ from Laravel's Str::random(). For tokens, passwords, and anything security-sensitive, use random_bytes() or Laravel's Str::random()/Str::uuid() and verify entropy from source before substituting.
Exceptions aren't Laravel exceptions. Some helpers throw JBZoo\Utils\Exception (or plain \Exception). Catch it explicitly; it won't be handled by Laravel's ValidationException → 422 pipeline.
Cli::* and Img::* have environment requirements. Cli helpers assume a CLI SAPI — don't call them from a controller. Img and some Colors paths may require the GD extension; guard with extension_loaded('gd') in commands rather than letting a runtime error escape.
Pin a version in composer.json. Utility libraries occasionally rename or adjust method signatures in minor releases. Given the fast release cadence, lock to a range you've tested and read the changelog on update.
Performance in hot loops. Some string helpers (slug transliteration tables, filter tables) load large static arrays on first use. That's fine once, but if you're processing thousands of strings, wrap the call in a static cache or precompute outside the loop.
Debugging is plain var_dump. There's no logging hook, no profiling, no event system. These are pure functions — print inputs and outputs directly. If a helper misbehaves, read src/; it's short and readable, and that's usually faster than chasing docs.
Extension points are limited. Most classes are final or static-only, so composition (not inheritance) is the supported path. If you find yourself wanting to override a method, wrap the class instead.
How can I help you explore Laravel packages today?