PHPackages                             apfelfrisch/query-filter - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Search &amp; Filtering](/categories/search)
4. /
5. apfelfrisch/query-filter

ActiveLibrary[Search &amp; Filtering](/categories/search)

apfelfrisch/query-filter
========================

A Framework agnostic query filter that sorts and filters queries using URL parameters

0.3.1(2y ago)37.3k↓33.3%MITPHPPHP ~8.1.0 || ~8.2.0 || ~8.3.0CI passing

Since Jan 20Pushed 5mo ago1 watchersCompare

[ Source](https://github.com/Apfelfrisch/query-filter)[ Packagist](https://packagist.org/packages/apfelfrisch/query-filter)[ RSS](/packages/apfelfrisch-query-filter/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (3)Dependencies (8)Versions (4)Used By (0)

Query Filter
============

[](#query-filter)

[![Unit tests](https://github.com/Apfelfrisch/query-filter/actions/workflows/phpunit.yml/badge.svg)](https://github.com/Apfelfrisch/query-filter/actions/workflows/phpunit.yml/badge.svg)[![Static Analysis](https://github.com/Apfelfrisch/query-filter/actions/workflows/phpstan.yml/badge.svg)](https://github.com/Apfelfrisch/query-filter/actions/workflows/phpstan.yml/badge.svg)[![Mutation tests](https://github.com/Apfelfrisch/query-filter/actions/workflows/infection.yml/badge.svg)](https://github.com/Apfelfrisch/query-filter/actions/workflows/infection.yml/badge.svg)

This Package provides a Framework agnostic Query Filter wich allows you to filter and sort queries based on the provided URL parameters. It comes with built-in adapters for Eloquent and Doctrine QueryBuilder, but can be extended to support other query building tools as well. The built-in URL parser supports basic [JSON API](https://jsonapi.org/) functionality, and can be swapped out for a customized parser if needed.

Yet another query filter - but why?
-----------------------------------

[](#yet-another-query-filter---but-why)

I was searching for a query-filter that separates the criteria builder from the SQL builder, this way the criteria can be created in one location and then passed to another, which is useful for adding them into repositories. Additionally, I needed the capability to write custom QueryBuilderAdapter for different implementations, mainly for using it with In-Memory Repositories for testing purposes.

Installation
------------

[](#installation)

`composer require apfelfrisch/query-filter`

Basic Usage
-----------

[](#basic-usage)

### Filter Users with the Name John

[](#filter-users-with-the-name-john)

`/users?filter[name]=John`

```
use Apfelfrisch\QueryFilter\QueryFilter;
use Apfelfrisch\QueryFilter\Adapters\EloquentQueryBuilder;

$queryBuilder = UserModel::query();

// Explicitly parse parameters
$users = QueryFilter::new()
  ->allowFilters('name')
  ->applyOn($queryBuilder, $request->all())
  ->get();

// Implicitly parse parameters over $_GET
$users = QueryFilter::new()
  ->allowFilters('name')
  ->applyOn($queryBuilder)
  ->get();

// Obtaining the CriteriaCollection which can be passed into a Repository, for example.
$criterias = QueryFilter::new()
  ->allowFilters('name')
  ->getCriterias();

$result = $criterias->applyOn(new EloquentQueryBuilder($queryBuilder))
```

### Filter Users with the Name John or Doe

[](#filter-users-with-the-name-john-or-doe)

`/users?filter[name]=John,Doe`

### Filter Users with name John and last name Doe

[](#filter-users-with-name-john-and-last-name-doe)

`/users?filter[name]=John&filter[lastname]=Doe`

```
$users = QueryFilter::new()
  ->allowFilters('name', 'lastname')
  ->applyOn($queryBuilder)
  ->get();
```

### Sort Users ascending by name

[](#sort-users-ascending-by-name)

`/users?sort=name`

```
$users = QueryFilter::new()
  ->allowSorts('name')
  ->applyOn($queryBuilder)
  ->get();
```

### Sort Users ascending by name and descending created\_at

[](#sort-users-ascending-by-name-and-descending-created_at)

`/users?sort=name,-created_at`

```
$users = QueryFilter::new()
  ->allowSorts('name', 'created_at')
  ->applyOn($queryBuilder)
  ->get();
```

### Allow only specfic fields

[](#allow-only-specfic-fields)

If needed, you can restrict the selected fields. If you do so, you must specify the fields via URI parameter. In the example below, only name and lastname will be selected.

`/users?fields=name,lastname`

```
$users = QueryFilter::new()
  ->allowFields('name', 'lastname', 'street')
  ->applyOn($queryBuilder)
  ->get();
```

### Skipping forbidden criterias

[](#skipping-forbidden-criterias)

By default, this package throws an exception if a filter or sort criteria is requested but not allowed. You can silently skip forbidden criterias like so:

```
use Apfelfrisch\QueryFilter\Settings;
use Apfelfrisch\QueryFilter\QueryFilter;

// via Settings injection
$settings = new Settings;
$settings->setSkipForbiddenCriterias();

new QueryFilter($settings);

// directly on the QueryFilter
QueryFilter::new()->skipForbiddenCriterias()
```

### Specify FilterCriteria

[](#specify-filtercriteria)

`/users?filter[name]=John`

```
use Apfelfrisch\QueryFilter\Criterias;

// Filter with name = "John"
$users = QueryFilter::new()
  ->allowFilters(new Criterias\ExactFilter('name'))
  ->applyOn($queryBuilder)
  ->get();

// Filter with name like "John%"
$users = QueryFilter::new()
  ->allowFilters(new Criterias\LeftStrictPartialFilter('name'))
  ->applyOn($queryBuilder)
  ->get();
```

### Write a custom Filter

[](#write-a-custom-filter)

Your customer Filter has to implement the [Filter interface](https://github.com/Apfelfrisch/query-filter/blob/main/src/Criterias/Filter.php). Concrete implementations can be found in the [Criterias](https://github.com/Apfelfrisch/query-filter/tree/main/src/Criterias) folder.

If you want to set your Filter as default, you can do it like so:

```
use Apfelfrisch\QueryFilter\Settings;
use Apfelfrisch\QueryFilter\QueryFilter;

$settings = new Settings();
$settings->setDefaultFilterClass(MyCustomerFilterClass::class);

$queryFilter = new QueryFilter($settings);
```

### Write custom QueryParser

[](#write-custom-queryparser)

todo

### Write custom QueryBuilderAdaper

[](#write-custom-querybuilderadaper)

todo

###  Health Score

37

—

LowBetter than 82% of packages

Maintenance52

Moderate activity, may be stable

Popularity26

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~208 days

Total

3

Last Release

788d ago

PHP version history (2 changes)0.1PHP ~8.1.0 || ~8.2.0

0.3.1PHP ~8.1.0 || ~8.2.0 || ~8.3.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/0c29824d3a2407bb8e98cd2a900525b81fdb9da742831dfee8127987d6d5df99?d=identicon)[Apfelfrisch](/maintainers/Apfelfrisch)

---

Top Contributors

[![Apfelfrisch](https://avatars.githubusercontent.com/u/4519207?v=4)](https://github.com/Apfelfrisch "Apfelfrisch (46 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/apfelfrisch-query-filter/health.svg)

```
[![Health](https://phpackages.com/badges/apfelfrisch-query-filter/health.svg)](https://phpackages.com/packages/apfelfrisch-query-filter)
```

###  Alternatives

[ruflin/elastica

Elasticsearch Client

2.3k50.4M202](/packages/ruflin-elastica)[opensearch-project/opensearch-php

PHP Client for OpenSearch

15024.3M64](/packages/opensearch-project-opensearch-php)[mailerlite/laravel-elasticsearch

An easy way to use the official PHP ElasticSearch client in your Laravel applications.

934529.3k2](/packages/mailerlite-laravel-elasticsearch)[massive/search-bundle

Massive Search Bundle

721.4M13](/packages/massive-search-bundle)[shyim/opensearch-php-dsl

OpenSearch/Elasticsearch DSL library

175.9M9](/packages/shyim-opensearch-php-dsl)[outl1ne/nova-multiselect-filter

Multiselect filter for Laravel Nova.

45802.7k3](/packages/outl1ne-nova-multiselect-filter)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
