PHPackages                             wp-media/apply-filters-typed - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. wp-media/apply-filters-typed

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

wp-media/apply-filters-typed
============================

Library for usage of WordPress filters in a safe-type way

v1.2(1y ago)2427.6k↓17.7%1[1 issues](https://github.com/wp-media/apply-filters-typed/issues)[1 PRs](https://github.com/wp-media/apply-filters-typed/pulls)6GPL-3.0-or-laterPHP

Since Jun 26Pushed 1y ago2 watchersCompare

[ Source](https://github.com/wp-media/apply-filters-typed)[ Packagist](https://packagist.org/packages/wp-media/apply-filters-typed)[ RSS](/packages/wp-media-apply-filters-typed/feed)WikiDiscussions develop Synced 1mo ago

READMEChangelog (3)Dependencies (5)Versions (6)Used By (6)

Apply Filters Typed
===================

[](#apply-filters-typed)

Library for usage of WordPress filters in a typesafe way.

What problem does it solve?
---------------------------

[](#what-problem-does-it-solve)

When using a filter with `apply_filters()`, there is currently no guarantee that the type of the final value (after all callbacks have been called) will match the type of the initial value for this filter.

This can cause unexpected errors in your code if you do some processing with this value later on, assuming the final value type is the same as the original one.

This library is a way to solve this problem, by introducing functions that are applying strict type checking.

It is also a a proof of concept for a WordPress change that has been proposed in this core ticket: .

Limitation
----------

[](#limitation)

If the end value type returned by the filter doesn't match the initial value type, the end value is discarded and the initial (default) one is returned. It's a limitation caused by the impossibility to access the internals of the hook system.

If the value is discarded, an error message will be added to the error.log when `WP_DEBUG` is enabled: `Return value of "hook_name" filter must be of the type "expected", "unexpected" returned.`

The patch proposed to core handles the situation better, discarding callbacks that return an unexpected type instead of discarding the final value.

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

[](#installation)

You can install the library using composer:

`composer require wp-media/apply-filters-typed`

Usage
-----

[](#usage)

You have 2 functions available to replace the default `apply_filters()` function:

### `wpm_apply_filters_typesafe( $hook_name, $value, ...$args )`

[](#wpm_apply_filters_typesafe-hook_name-value-args-)

This function takes the same parameters as the `apply_filters()` function. It will automatically determine the type to use for validation by checking the type of the `$value` parameter.

### `wpm_apply_filters_typed( $type, $hook_name, $value,  ...$args )`

[](#wpm_apply_filters_typed-type-hook_name-value--args-)

This function takes as its first parameter the expected type of the value to be filtered, in addition to the usual parameters of the `apply_filters()` function.

In the context of WordPress, the common types would be:

- boolean
- integer
- double
- string
- array
- object

Since v1.2, the following are also supported:

- Union types (i.e. `int|string`)
- Nullable types (i.e. `?string`)
- Typed arrays (i.e. `string[]`)

Create your own type validation
-------------------------------

[](#create-your-own-type-validation)

If you have a need for more complex type validation of the value passed to the filter, for example in case of an array composed of items of a specific instance, you can use the dynamic filter `wpm_is_type_{$type}`, where `$type` would match with the `$type` value you pass to `wpm_apply_filters_typed()`.

Here is an example to do custom type validation on an array of strings: `wpm_apply_filters_typed( 'Product[]', 'filter_this_array', $value );`

```
add_filter( 'wpm_is_type_string[], function( $value ) {
    if ( ! is_array( $value ) ) {
        return false;
    }

    foreach ( $value as $val ) {
        if ( ! $val instanceOf Product ) {
            return false;
        }
    }

    return true;
} );

```

###  Health Score

34

—

LowBetter than 77% of packages

Maintenance25

Infrequent updates — may be unmaintained

Popularity40

Moderate usage in the ecosystem

Community18

Small or concentrated contributor base

Maturity44

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 56.3% 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 ~33 days

Total

3

Last Release

610d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/5564218f7cd2ccf4542a09b7c5436e61e6b370c97fb3b04db1c5bbc0cc67e3c1?d=identicon)[wpmedia](/maintainers/wpmedia)

---

Top Contributors

[![remyperona](https://avatars.githubusercontent.com/u/3465180?v=4)](https://github.com/remyperona "remyperona (9 commits)")[![MathieuLamiot](https://avatars.githubusercontent.com/u/15233030?v=4)](https://github.com/MathieuLamiot "MathieuLamiot (7 commits)")

### Embed Badge

![Health badge](/badges/wp-media-apply-filters-typed/health.svg)

```
[![Health](https://phpackages.com/badges/wp-media-apply-filters-typed/health.svg)](https://phpackages.com/packages/wp-media-apply-filters-typed)
```

PHPackages © 2026

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