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

Binput Laravel Package

graham-campbell/binput

Binput is a Laravel input cleaner that sanitises user input via HTMLPurifier, stripping dangerous markup while keeping safe content. It handles strings and arrays, supports cleaning types such as default, html, url and query, and integrates through a simple facade for safer request data.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. Binput is a thin, framework-native facade over Laravel's input retrieval — a single service provider, a Binput alias, and a wrapper that reads query strings, form bodies, and JSON payloads through one accessor. Architecturally it slots in at the HTTP boundary as a reader, not a transformer: controllers, Form Requests, and API resources call Binput::get('key', $default) instead of mixing request()->input(), request()->query(), and json_decode($request->getContent(), true). That is a real, if modest, consistency win on endpoints that accept both form-encoded and JSON clients. It is not middleware, it does not touch every request, and it does not sanitize, validate, or neutralize anything. The "Input Protector" framing in the package description and in the supplied PM notes is a positioning error we should correct before it reaches a roadmap review — treating this as a security control would create false confidence in exactly the way that matters least and costs most.

Integration feasibility. Low effort. composer require graham-campbell/binput, auto-discovery registers the provider and alias, php artisan about confirms it booted. Total surface is small enough to read end-to-end in an afternoon, which is the right pre-adoption gate for anything that will appear in request-handling code. No config publishing, no migrations, no bootstrapping, no queue or scheduler coupling. The realistic adoption unit is one vertical slice: convert one endpoint's input reads, add characterization tests for application/x-www-form-urlencoded, application/json, and query-string access, review the diff, then expand.

Technical risk. Three distinct risks, in order of severity:

  1. Category risk — it will be mistaken for a security fix. The name and description invite a stakeholder to conclude that stored XSS or unvalidated input is now handled. It isn't. If this package lands in a hardening sprint without an explicit written correction, we will ship a non-mitigation and mark a finding closed. That is the dominant risk here and it is organizational, not technical.
  2. Maintenance risk — single maintainer, zero dependents, score 0.3. v11.1.0 adds Laravel 11 support, which tells us the maintainer is alive today, not that L12/L13 land on a schedule we can plan against. Laravel 12 is unclaimed. A dependency that silently fails to boot on the next major is worse than no dependency, because the failure surfaces later as something else.
  3. Behavioural risk — edge-case semantics. Missing key returning null vs '', interaction with ConvertEmptyStringsToNull and required/nullable, nested JSON ({"user":{"name":"x"}}) and dot-notation (Binput::get('user.name')). Each is cheap to test and expensive to discover in production. Also: it does not read uploaded files — $request->file() remains the path — and the Binput alias can collide with a model or DTO of the same name.

Key questions.

  • What is the actual, demonstrated problem — are we seeing inconsistent input reads across form and JSON endpoints, or are we pattern-matching on the word "protector"?
  • Who owns the written house rule ("escape on output, always" vs. "sanitize on input")? Without that sentence committed to team docs, the next developer will treat Binput as a sanitizer.
  • Does composer.json constrain illuminate/* and php in a way that fits our app, and have we confirmed Laravel 12 behaviour rather than assumed it?
  • Are we prepared to vendor or fork it and carry characterization tests, or are we taking it as a trusted dependency? Those are different commitments.
  • Does the name collision risk exist in our codebase today?

Integration Approach

Stack fit. Fits Laravel 8–11 apps on the matching release line; v11.1.0 implies PHP 8.2+ and Laravel 11. It is framework-native — no custom container bindings, no config surface, no opinion about how we structure controllers. It composes cleanly with Form Requests (prepareForValidation() can trim via Binput::get() before rules run), with API Resources, and with queued jobs and console commands, since a facade has no HTTP-boundary limitation. It does not fit alongside a parallel input-sanitization layer; pick output escaping or input sanitization for any given field, never both, or we produce double-encoded output (<) that corrupts legitimate content and generates a support queue about mangled apostrophes.

Migration path. Incremental by design, and it should stay that way. Do not rewrite every request()->input() call in one PR. Sequence: (1) read README.md, src/, and composer.json end-to-end; (2) pick one endpoint with genuine mixed-content-type traffic; (3) convert reads to Binput::get() with explicit defaults; (4) add characterization tests asserting response shape for form-encoded, JSON, and query-string; (5) add a test for a missing key and an empty-string value; (6) review the diff; (7) expand only after the first slice is quiet in staging. Roll out behind a flag or per-route, not globally — this is a reader, so a global cutover has no safety benefit and multiplies blast radius if a semantic surprise exists.

Compatibility. The gating item is version, not code. Pin the exact release. Add "re-run input characterization tests on framework major upgrade" to the upgrade checklist, because the failure mode is a silent boot failure or a changed default, not a loud exception. If we are standardizing on Laravel 12, treat this as unverified until our own suite passes — do not extend the L11 claim forward by optimism. File uploads stay on $request->file()/hasFile() and are out of scope. Verify Binput alias absence in our own namespaces before install.

Sequencing. Do the policy decision before the technical install. The order that works: (a) write the house rule for input handling and output escaping and get it into team docs; (b) confirm the demonstrated problem this solves; (c) decide vendor/fork vs. depend; (d) install and convert one slice; (e) expand. Doing (d) before (a) is how a consistency utility becomes an accidental security theater artifact. If the honest answer at step (b) is "nothing is broken; we just want tidier controllers," this is a refactor ticket, not a hardening ticket, and should be scheduled and resourced as such.

Operational Impact

Maintenance. Effectively zero ongoing cost if it stays a reader — one facade, no config, no schema, no background work. The real maintenance burden is the fork/vendor decision: with a single maintainer and zero dependents, we should treat this as source we own. Vendoring it into the repo, pinning the version, and wrapping it in our own characterization tests converts "abandoned package causes an outage" into "routine maintenance chore." That is the trade I would recommend — the package is small enough that owning it is cheaper than the governance cost of tracking an unmaintained dependency.

Support. No vendor, no SLA, no community to escalate to. Internal support means one or two engineers who have read src/ and can debug a surprise value — reproduce with curl, log Binput::get('key') and $request->input('key') side by side, and the difference (content type, dot-notation, or default) is immediately visible. That is a fast path, but it depends on someone having done the reading. Budget one afternoon for that person up front, and document the debugging recipe alongside the house rule.

Scaling. Negligible technical scaling concern — it is a synchronous in-process read with no I/O, no cache, no state. It scales exactly as Laravel's request object does. The scaling concern is organizational: every additional endpoint converted adds a small surface where a developer might believe validation has already happened. The mitigation is the written contract at the call site — Binput::get() → Form Request validation → DTO/Model → output escaping — repeated in review until it is reflexive.

Failure modes.

  • Silent non-mitigation: installed and assumed to be sanitizing. Highest-likelihood, highest-impact. Mitigate with an explicit correction in the ticket and in the written house rule.
  • Framework-major boot failure: package stops working on L12+ without a loud signal, manufacturing false confidence. Mitigate by pinning and testing on every major.
  • Double-encoding: if anyone wraps Binput with tag-stripping or HTML escaping, legitimate content corrupts on output. Mitigate by choosing one policy and enforcing it in review.
  • Semantic drift at the edges: missing key vs. empty string, nested JSON, dot-notation. Mitigate with characterization tests, not code review.
  • Alias collision: a Binput model or service in our codebase fails to resolve. Mitigate with a namespace check pre-install.
  • False scope: expectations that it covers file uploads, mass assignment, IDOR, or tenancy leaks. It covers none of these; those remain $fillable/$guarded, policies, and scoped queries.

Ramp-up. Very low for an engineer already fluent in Laravel — an afternoon of reading plus one converted endpoint is sufficient. Non-trivial for the organization, which must absorb: a corrected mental model of what the package does, a written input-handling policy, a vendor/fork decision, an upgrade-checklist line, and a review habit. That organizational work is where the actual cost sits, and it is worth doing regardless of whether we adopt this package — which is arguably the strongest argument for the assessment: the policy work has standalone value, the library is optional, and the two should be evaluated separately rather than bundled into a single "should we adopt Binput" decision.

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