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

Util Bundle Laravel Package

svc/util-bundle

A PHP utility bundle that collects shared helpers and common services in one place, helping reduce boilerplate and keep reusable functionality consistent across projects. svc/util-bundle is aimed at simpler maintenance, faster setup, and cleaner Laravel/PHP applications.

View on GitHub
Deep Wiki
Context7

Getting Started

First, the framework reality check. Despite the "util" name, svc/util-bundle is a Symfony bundle — the Bundle suffix and Sven-Ve\Svc namespace give it away. There is no Laravel service provider, no facade, no config/util.php to publish, and no auto-discovery. In a Laravel app you have two realistic paths:

  1. composer require svc/util-bundle and instantiate the helper classes directly (autoloading works; the Symfony DI wiring is inert).
  2. Read the source and port the 2–3 classes you actually need into app/Support/Util/. At 3 stars, 0 dependents, and a single maintainer, this is usually the better call.

Minimal steps (inspect-first, for the port path):

composer require svc/util-bundle --prefer-source   # pull source so you can read it

Then, before writing a single line of app code:

# Enumerate the public surface — this is what you're actually adopting
find vendor/svc/util-bundle/src -name '*.php' -type f | sort

Open the network, environment, and mail helper classes line by line. You are deciding whether to port or depend; the source is the only documentation.

First use case that survives contact with a Laravel app: the network helper's client-IP resolution. Laravel's Request::ip() respects TrustProxies but is coarse for multi-hop CDNs and gives you little visibility into why it picked an address. A small diagnostic endpoint or admin "who am I" panel that surfaces the resolved IP plus the header precedence used is a genuinely useful debugging tool:

// app/Http/Controllers/Diagnostics/ClientController.php
public function show(Request $request)
{
    return response()->json([
        'laravel_ip'    => $request->ip(),
        'forwarded_for' => $request->header('X-Forwarded-For'),
        'real_ip'       => $request->header('X-Real-IP'),
        'cf_connecting' => $request->header('CF-Connecting-IP'),
    ]);
}

Note that this sample is all Laravel primitives — it works without the package. That's the point: run the spike, and if the package's helper doesn't beat three lines of $request->header(), port or skip it.

Implementation Patterns

Wrap, never call directly. Regardless of which helpers survive your spike, do not scatter static calls across controllers and jobs. Put a first-party interface in front of them so the dependency is swappable and you can test against your contract rather than the package's behavior.

// app/Support/Util/NetworkInfo.php
namespace App\Support\Util;

interface NetworkInfo
{
    public function clientIp(\Illuminate\Http\Request $request): string;
}

// app/Support/Util/BundleNetworkInfo.php
class BundleNetworkInfo implements NetworkInfo
{
    public function clientIp(\Illuminate\Http\Request $request): string
    {
        // Ported or wrapped resolution — the point is the class boundary.
        return $this->resolve($request);
    }
}
// app/Providers/AppServiceProvider.php
$this->app->bind(\App\Support\Util\NetworkInfo::class, \App\Support\Util\BundleNetworkInfo::class);

Environment helpers: config-time only. If the package offers env detection (isProduction(), getEnv(), etc.), call it inside config files only, never from a controller or job. Laravel's config:cache flattens env() at deploy time; any per-request env() call hits the filesystem, breaks under Octane's long-lived workers (stale values across requests), and produces the classic "works in staging, wrong in prod after deploy" bug. The correct pattern is:

// config/app.php or a dedicated config/util.php
'env_name' => (string) env('APP_ENV', 'production'),
'debug'    => (bool) env('APP_DEBUG', false),

Then read config('app.env_name') everywhere else. Never App\Support\Util\Env::get() per request.

Mail helper: route it through Laravel's Mail facade. If you decide the package's mail transport config is worth keeping, use it only to build a mailer, never to send directly. Anything that instantiates a Swift_Mailer/Symfony\Component\Mailer\Mailer directly bypasses the Mailer contract, which means:

  • Mail::fake() in tests will not intercept your sends — you get silent delivery attempts during test suites;
  • events (MessageSending, MessageSent) don't fire, so logging and monitoring go blind;
  • notifications and queued mail bypass the queue.

Correct usage pattern:

// Set config from the helper at boot, then use Laravel's Mail normally.
// config/mail.php reads env(), and the package (if kept) informs those values.
Mail::to($user)->send(new WelcomeMail($user));   // always this, never the package's send()

Porting pattern for the environment helper. If you go the vendoring route, keep the class in app/Support/Util/ and give it a test that asserts your expected behavior, not the package's:

public function testEnvironmentDetectionHandlesConfigCache()
{
    putenv('APP_ENV=production');
    $this->assertTrue(app(Env::class)->isProduction());

    // Simulate config:cache flattening
    config(['app.env_name' => 'staging']);
    $this->assertSame('staging', config('app.env_name'));
}

The pattern that matters is: the adapter's tests define your contract, not the package's implementation. That's what lets you swap or fork without a rewrite.

Gotchas and Tips

It is not a Laravel package — stop expecting Laravel ergonomics. No auto-discovery, no Util::network()->ip(), no publishable config. The Symfony bundle class is dead weight in Laravel and will confuse anyone reading composer.json later. If you adopt, document in your README why a Symfony bundle is a dependency of a Laravel app — otherwise someone will remove it as "unused" during a dependency audit and break the build.

The env() / config:cache trap is the number-one production incident source. Symfony-style env helpers that read $_ENV or getenv() per call will:

  • return stale values under Octane (the worker process env doesn't change between requests, but config doesn't re-read either);
  • miss values injected by your orchestrator (ECS/Kubernetes task-definition env) if config was built before that injection;
  • return null after config:cache if the helper is used outside a config file.

Grep your codebase before adopting for any direct use of getenv(), $_ENV, or $_SERVER — if the package normalizes those, it will normalize the same broken way in every entry point, and you lose per-context control. In Laravel the correct fix is config('…'), full stop.

Network helper: verify timeouts and header precedence. The package's value proposition (proxy parsing) is also its risk surface. Before relying on it:

  • Confirm it sets explicit connect and read timeouts. A helper that wraps file_get_contents with no timeout will hang a queue worker on a flaky network call.
  • Confirm header precedence is explicit and documented. X-Forwarded-For order varies between Cloudflare, AWS ALB, nginx, and Traefik — pick a precedence, write it in a comment, and test it against a mocked request with all headers set.
  • Never feed the resolved IP into authorization, rate limiting, or access control without a review. At 3 stars and 0 dependents, you are the security reviewer. A proxy-header bug here is a privilege-escalation bug, not a diagnostic inconvenience.

Mail helper: three specific test-coverage holes to check.

# 1. Does the helper call Mailer directly?
grep -R "new .*Mailer\|Swift_Mailer\|Symfony\Component\Mailer" vendor/svc/util-bundle/src

# 2. Does it leak credentials into exceptions?
grep -R "password\|secret\|token" vendor/svc/util-bundle/src
  • If Mail::fake() doesn't intercept, your test suite is actually sending mail (or trying to, and silently failing to localhost:25 — which is worse because it hides the fact that tests never verify mail).
  • Verify the helper never echoes SMTP credentials into a log or exception string. A package that dumps the transport config on connection failure will send credentials to Sentry on the first DNS hiccup.

Extension points are near zero — assume fork.

  • No Laravel service provider means no app()['svc.util'] singleton to decorate.
  • No published config means you can't override defaults without forking the PHP.
  • MIT license means forking is legally trivial, which is the only reliable extension path here.

The pragmatic play: composer require, read the two or three classes you care about, copy them into app/Support/Util/, add a @see comment pointing at the upstream repo, and composer remove. You keep the convenience, drop the supply-chain surface, and remove the "who maintains this?" question from your next incident review.

Debugging technique — when something looks environmental, it's usually config cache, not the package. Standard triage:

php artisan config:clear
php artisan config:cache
php artisan tinker --execute "dump(config('app.env'), env('APP_ENV'))"

If env() and config() disagree in tinker, your config was built before the env var was set — a deploy ordering bug, not a package bug. Fix the deploy; don't patch the helper.

The maintenance reality. Single maintainer, 3 stars, zero dependents, no support policy, no CI matrix advertised. Any engineer can read the entire API in under an hour (ramp-up cost is low), but the due diligence — checking the test suite, verifying timeout enforcement, auditing the mail path, wrapping it behind an adapter — is disproportionate to a package whose total value is likely a few dozen lines of convenience. If your PoC cannot articulate a gap versus $request->ip(), config(), and Mail, the correct answer is to skip the dependency. The port is under a day and gives you a first-party class with tests that fail your way, not someone else's.

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.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core