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 Search Query Builder Laravel Package

djl997/laravel-search-query-builder

A Laravel package offering a fluent query builder for composing search filters and database queries, helping you keep complex search logic clean, reusable, and easy to maintain across your application.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install with composer require the package version you need, then check the package README and the newly added tests/ directory first — the test suite is the most reliable source of truth for the exact search() signature and expected behaviour in 1.4.0.

  • The primary entry point is the search() method on a query builder. Start with a raw query builder to confirm behaviour before layering it into Eloquent:

    $results = DB::table('users')
        ->search(['first_name', 'last_name', 'email'], 'jane doe')
        ->get();
    
  • First use case: a simple admin list search box. Pass the user-supplied term and the columns you want matched; the package splits on commas and applies the matching logic for you.

  • If you are on Laravel 9–13, 1.4.0 is the first release with a documented CI matrix across those versions, so it is the safest starting point.

Implementation Patterns

  • Chaining after search(): 1.4.0 fixed search() returning null instead of the builder. You can now freely chain:

    DB::table('orders')
        ->search(['customer_name', 'reference'], $term)
        ->where('status', 'open')
        ->orderBy('created_at', 'desc')
        ->paginate(25);
    
  • Comma-separated multi-term input: terms like "foo,bar" are split and treated as separate search terms. Normalise user input (trim, collapse whitespace) before passing it in, and decide explicitly what should happen when the resulting term list is empty.

  • Reserved-word columns: columns named order, group, key, etc. now work because identifiers are quoted by the grammar. Prefer these names over workarounds like aliasing.

  • Eloquent integration: use it on a query builder obtained from a model (Model::query()->search(...)) or on DB::table(); keep the search scoped to a single query so it composes cleanly with existing scopes and filters.

  • Validation gate: pair the search with request validation so an all-whitespace or punctuation-only term is treated as “no filter” at the application layer rather than relying on SQL semantics.

  • Testing: with the new suite in place, write an integration test asserting your expected result set for a known term, plus a regression test that an empty term does not return every row.

Gotchas and Tips

  • Breaking change — raw SQL column expressions are no longer supported. Columns such as CONCAT(first_name, last_name) passed to search() used to work and now do not, because identifiers are grammar-quoted. Audit any call sites that pass expressions, and replace them with real columns or a separate whereRaw/subquery-based search.
  • Empty terms no longer match everything. Previously "foo,", "foo,,bar", or a whitespace-only term could match all rows — a potential data-exposure bug if you relied on the old behaviour. Verify the new no-match behaviour matches your UX expectations, and handle empty input explicitly.
  • search() return value changed. Code that assigned the result ($q = $q->search(...)) and then checked for null will behave differently; code that assumed it could not chain is now unnecessarily verbose. Search your codebase for any defensive null checks.
  • Reserved-word quoting is grammar-dependent. Behaviour should be consistent across MySQL/Postgres/SQLite, but if you support multiple drivers, add a smoke test per driver — quoting rules are the classic source of cross-database drift.
  • Extension point: since raw expressions are out, compose complex search predicates by combining search() with whereRaw/orWhere rather than trying to smuggle SQL into the column list. Keep the raw fragments parameterised.
  • Debugging: call ->toSql() and ->getBindings() before get() to inspect how terms and quoted identifiers are rendered — most surprises are empty-term handling or identifier quoting, both visible in the compiled SQL.
  • Version pinning: because the raw-expression support was removed in a patch-minor, pin to ^1.4 only after confirming no call site passes expressions; otherwise stay on the previous line until you have migrated 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.
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk