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

Laravel Heyman Laravel Package

imanghafoori/laravel-heyman

Laravel Heyman adds a layer of defensive authorization to Laravel apps: heyman()->can() and cannot() check gates and policies and throw exceptions on failure, with Blade directives and model-level helpers so you can guard actions consistently without repeating boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

Install with Composer; Laravel's package auto-discovery registers the service provider, so no manual wiring is needed:

composer require imanghafoori/laravel-heyman

The single entry point is the global heyman() helper (there is also a facade/container binding, but the helper is the idiomatic path). The first use case to reach for is guarding a method's preconditions — especially in service classes, actions, jobs, and Artisan commands where an argument arrives from a config file, a container resolution, or a loose caller rather than from a FormRequest:

public function send(string $channel, $payload): void
{
    heyman()->ensureString($channel);
    heyman()->ensureNotEmpty($payload);
    heyman()->ensureArray($payload);

    // From here you can trust the inputs.
}

Look first at the README's method table — the package is essentially a catalogue of ensureXxx checks (ensureString, ensureInt, ensureBool, ensureArray, ensureObject, ensureNotEmpty, ensureNotNull, ensureClassExists, ensureInterfaceExists, ensureMethodExists, ensurePropertyExists, plus ensureNullableXxx variants). Pick the two or three checks you need at function boundaries and stop there; it's not a framework to learn.

Implementation Patterns

Guard clauses at method entry. The canonical pattern is a small block of heyman()->ensureXxx() calls at the top of a public method, before any side effects. This replaces hand-rolled if (...) { throw new InvalidArgumentException(...) } boilerplate and keeps the happy path readable.

Dynamic instantiation / reflection. Before new $class() or call_user_func([$obj, $method]), use ensureClassExists, ensureInterfaceExists, ensureMethodExists, and ensurePropertyExists. This is where the package pays off most — you get a clear, located failure instead of a fatal error deep in the call stack.

In DTOs and value objects. Constructor guards are a natural fit:

final class Money
{
    public function __construct(public int $amount, public string $currency)
    {
        heyman()->ensureInt($amount);
        heyman()->ensureNotEmpty($currency);
    }
}

Every downstream consumer then benefits from the invariant without repeating checks.

Integration with Laravel idioms. Think of it as a developer-facing companion to abort_if() and throw_unless(). Where those are aimed at HTTP-level failures (e.g. 404s), HeyMan is aimed at programmer errors — wrong type, null where null is not allowed, missing class. Use abort_if for user-facing 4xx semantics and HeyMan for internal contract violations.

Contrast with assert(). PHP's assert() is compiled out in production (zend.assertions = -1), so it silently disappears exactly where you need it. HeyMan always runs; this is the main reason to prefer it in libraries and internal packages.

Testing. In feature/unit tests, assert failures with $this->expectException(\Imanghafoori\HeyMan\Exceptions\HeyManException::class) (or the precise subclass in the current release) and verify both the happy path and each guard.

Gotchas and Tips

Do not use it for user input validation. HeyMan throws an exception, which in Laravel becomes a 500 — not the 422 that FormRequests, Validator, and assert()-style checks produce. Validate request data with the normal Laravel tools; use HeyMan only for inputs you believe are already correct.

Strict types bite. With declare(strict_types=1), ensureInt('5') will fail on the string '5'. That's usually what you want, but it surprises people coming from is_numeric. If a value is legitimately coerced upstream, coerce it explicitly before calling ensureInt.

Be intentional about nullable vs. non-nullable. The library ships both ensureXxx and ensureNullableXxx for several types. Choosing the wrong one is the most common source of "works in dev, throws in prod" bugs — decide the contract explicitly and mirror it in the test suite.

Throw cost. Exceptions are expensive to construct. This is fine for guard clauses (failure path only), but avoid putting HeyMan checks inside tight loops where failures are a normal, tolerated condition. If a failure is expected and handled, a plain boolean branch is cheaper.

Distinguish it from Laravel validation. The exception messages are developer-facing ("the argument you passed is not an array") and include caller-location context, which is great in Sentry logs but meaningless to end users. If you ever surface a HeyMan failure to a browser, you've leaked an internal contract violation — treat it as an alert, not a UX message.

Override the exception for central handling. If you want a single place to convert internal contract violations into your own exception/logging channel, publish and edit the package config (optional, but the supported extension point) to point at a custom exception class, then handle it once in App\Exceptions\Handler.

Autoload / helper availability. The heyman() helper is registered by the service provider's helpers autoload block. In a non-standard bootstrap (custom skeletons, package test harnesses, older Lumen), you may need to require the helper file or rely on the container binding instead of the global function.

Debugging failed guards. The exception message and trace point at the failing check — read the top frames, not the bottom. If a guard fails only in CI, check PHP version differences (strict_types, int/float coercion) and whether the caller is passing null from a config key that is absent in that environment.

Keep it shallow. Adding guards for every parameter in every method quickly becomes noise. Reserve HeyMan for public boundaries (controllers → services, services → domain, container resolution) and trust types inside a class once the constructor has validated them.

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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console