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

Eloquent Array Query Builder Laravel Package

williamoliveira/eloquent-array-query-builder

Query PHP arrays with a familiar Eloquent-style API. Filter, sort, group, and paginate in-memory data using where, orderBy, and limit methods, bringing Laravel's query builder ergonomics to plain arrays and collections without touching a database.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package alongside your Laravel app:

composer require williamoliveira/eloquent-array-query-builder

Look at the package README.md first — it is the only authoritative reference for the array schema (key names differ between releases of similar “array query” packages). The core idea is that instead of chaining ->where()->orderBy()->limit() on a builder, you hand the package an associative array describing the query and it builds the equivalent Eloquent chain for you.

The first use case to try is a simple filtered index: take an associative array of filters (status, date range, sort), pass it to the model, and get back a normal Eloquent Builder or Collection. Once that matches the equivalent hand-written query via toSql(), extend it to joins or eager loads.

Typical entry point (verify against the README for your installed version — the method name is the one thing most likely to change between forks):

use App\Models\User;
use WilliamOliveira\EloquentArrayQueryBuilder\...; // trait or facade namespace per README

$users = User::arrayQuery([
    'where'   => ['status' => 'active'],
    'orderBy' => ['created_at', 'desc'],
    'limit'   => 25,
])->get();

Confirm the builder is returned (not a Collection) before you paginate or eager-load — most of the implementation decisions below depend on that.

Implementation Patterns

Request filters as arrays. The natural fit is an IndexRequest → array → query pipeline. Build a small assembler (e.g. UserFilter) that maps validated request fields into the package’s array shape, so controllers stay short and the array schema is defined in one place.

$query = User::arrayQuery($filters->toArray())
    ->with(['team'])          // only if the package returns a Builder
    ->paginate(25);

Composability. If the package returns an Illuminate\Database\Eloquent\Builder, you can keep chaining standard methods after arrayQuery(). Treat the array form as a starting point and add scopes, with(), when(), etc. afterwards. This is the safest way to use an old package: let it do the boring where/orderBy translation, and use stock Eloquent for anything exotic.

Layered filters. Common pattern: a base array for fixed conditions (tenant_id, deleted_at is null) merged with a user-supplied array for the variable parts. Use array_merge_recursive carefully — where keys collide if you merge naively; prefer two separate calls: User::arrayQuery($base)->arrayQuery($filters) if supported, otherwise $base + $filters or a whitelist merge.

Whitelisting keys. Because the array keys map to SQL, define an allowlist of supported keys and operators (where, orWhere, whereIn, orderBy, limit, offset) in your filter class. This protects against a request field accidentally landing in the array and either erroring or widening the query.

Integration with FormRequests. Validate the values (dates, enum statuses) in a FormRequest, then transform to the array shape. Do not let raw request()->all() reach the package — array keys coming from user input is a SQL-injection-adjacent smell even when values are bound.

Testing. Assert on ->toSql() and ->getBindings() against a hand-written Eloquent equivalent — this is the only reliable way to know the package emits what you expect, and it lets you swap the package out later with confidence.

Gotchas and Tips

Maintenance risk is the headline. Last release was August 2020, ~18 stars. It predates Laravel 9’s type changes and Laravel 10/11’s method signature tightening on Builder. Expect to either pin Laravel to the era the package targeted, fork it, or copy the trait into your app (app/Support/ArrayQueryBuilder.php). Forking is cheap here — the package is small.

Verify the return type early. Some versions return a Builder, some execute immediately. If it executes, ->with(), ->paginate(), and ->when() all fail with confusing errors. dd($result) on day one.

Operator and value semantics. Array-based builders typically infer = and only special-case a handful of operators. Test null, arrays (for whereIn), and zero/empty-string values explicitly — ['status' => null] may produce status is null or status = null (always-false), depending on version.

Nested relations and whereHas are usually not supported. If you need whereHas('orders', ...) or whereColumn, drop back to native Eloquent. Don’t force the array form for complex relationships.

Debugging. When a query looks wrong, call ->toSql() and ->getBindings() and diff against the manual equivalent. If the package builds through a facade or macro, Builder::macro conflicts with other packages (e.g. Telescope, IDE helper) can mask the original method — check composer show and app/Providers for conflicting macro registrations.

Order-by shape. The orderBy value is the field most likely to differ between versions: some take ['column', 'dir'], others ['column' => 'dir']. Confirm from the README, and normalise user input in your filter class so the rest of the app isn’t coupled to the package’s shape.

Empty arrays. arrayQuery([]) should be a no-op but is a common source of “all rows” bugs when a filter assembler returns empty — guard against it in the filter class, and test that an empty filter yields the same result as Model::query().

Upgrade path. Keep the array-building logic in a dedicated class implementing a small interface (build(array $filters): Builder). That way, when the package stops working on Laravel 12, you replace one class with standard Eloquent and nothing else in the app knows the difference.

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.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log