# RFC: Add Filter\Filter and Filter\Flag Enums

- Status: Under discussion
- Authors: Muhammed Arshid, arshidkv12@gmail.com
- Date: 2026-10-03
- Version: 0.9
- Implementation: https://github.com/php/php-src/pull/24111
- Original: https://wiki.php.net/rfc/invalid_filter_options
- Page: https://externals.io/rfc/invalid_filter_options
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

## Votes

### Implement Filter\Filter and Filter\Flag enums as outlined in the RFC? (closed)

Yes: 0 · No: 0 · Abstain: 0

## Discussions on the mailing list

- [\[RFC\] Deprecate Invalid Filter Options](https://externals.io/message/132778.md) — started on 2026-10-03, 10 messages

---

## Introduction

The Filter extension currently exposes filter IDs and filter flags primarily as integer constants such as `FILTER_VALIDATE_INT` and `FILTER_FLAG_ALLOW_HEX`.

These constants remain widely used and will continue to be supported. However, using integers for filter IDs and flags provides little type information and makes the API less discoverable when using modern PHP type systems.

This RFC proposes adding two backed enums:

- `Filter\Filter` for filter IDs.
- `Filter\Flag` for filter flags.

The enums provide a typed and discoverable alternative while preserving the existing integer constants and APIs.

## Proposal

Add the following two backed enums:

```php
namespace Filter;
enum Filter: int
{
  case DEFAULT = FILTER_DEFAULT;
 
  case VALIDATE_BOOL = FILTER_VALIDATE_BOOL;
  case VALIDATE_INT = FILTER_VALIDATE_INT;
  case VALIDATE_FLOAT = FILTER_VALIDATE_FLOAT;
  case VALIDATE_REGEXP = FILTER_VALIDATE_REGEXP;
  case VALIDATE_DOMAIN = FILTER_VALIDATE_DOMAIN;
  case VALIDATE_URL = FILTER_VALIDATE_URL;
  case VALIDATE_EMAIL = FILTER_VALIDATE_EMAIL;
  case VALIDATE_IP = FILTER_VALIDATE_IP;
  case VALIDATE_MAC = FILTER_VALIDATE_MAC;
 
  case SANITIZE_STRING = FILTER_SANITIZE_STRING;
  case SANITIZE_EMAIL = FILTER_SANITIZE_EMAIL;
  case SANITIZE_URL = FILTER_SANITIZE_URL;
  case SANITIZE_NUMBER_INT = FILTER_SANITIZE_NUMBER_INT;
  case SANITIZE_NUMBER_FLOAT = FILTER_SANITIZE_NUMBER_FLOAT;
  case SANITIZE_SPECIAL_CHARS = FILTER_SANITIZE_SPECIAL_CHARS;
  case SANITIZE_FULL_SPECIAL_CHARS = FILTER_SANITIZE_FULL_SPECIAL_CHARS;
  case SANITIZE_ADD_SLASHES = FILTER_SANITIZE_ADD_SLASHES;
 
  case CALLBACK = FILTER_CALLBACK;
}
 
 
enum Flag: int
{
  case NONE = FILTER_FLAG_NONE;
 
  case ALLOW_OCTAL = FILTER_FLAG_ALLOW_OCTAL;
  case ALLOW_HEX = FILTER_FLAG_ALLOW_HEX;
 
  case STRIP_LOW = FILTER_FLAG_STRIP_LOW;
  case STRIP_HIGH = FILTER_FLAG_STRIP_HIGH;
  case STRIP_BACKTICK = FILTER_FLAG_STRIP_BACKTICK;
 
  case ENCODE_LOW = FILTER_FLAG_ENCODE_LOW;
  case ENCODE_HIGH = FILTER_FLAG_ENCODE_HIGH;
  case ENCODE_AMP = FILTER_FLAG_ENCODE_AMP;
  case NO_ENCODE_QUOTES = FILTER_FLAG_NO_ENCODE_QUOTES;
  case EMPTY_STRING_NULL = FILTER_FLAG_EMPTY_STRING_NULL;
 
  case ALLOW_FRACTION = FILTER_FLAG_ALLOW_FRACTION;
  case ALLOW_THOUSAND = FILTER_FLAG_ALLOW_THOUSAND;
  case ALLOW_SCIENTIFIC = FILTER_FLAG_ALLOW_SCIENTIFIC;
 
  case PATH_REQUIRED = FILTER_FLAG_PATH_REQUIRED;
  case QUERY_REQUIRED = FILTER_FLAG_QUERY_REQUIRED;
 
  case IPV4 = FILTER_FLAG_IPV4;
  case IPV6 = FILTER_FLAG_IPV6;
  case NO_RES_RANGE = FILTER_FLAG_NO_RES_RANGE;
  case NO_PRIV_RANGE = FILTER_FLAG_NO_PRIV_RANGE;
  case GLOBAL_RANGE = FILTER_FLAG_GLOBAL_RANGE;
}
```

The enums are backed by int, matching the existing representation of Filter IDs and flags.

## API Changes

The four Filter functions will accept the new `Filter\Filter` and `Filter\Flag` enums in addition to the existing integer values.

### filter\_var()

A filter can be specified using `Filter\Filter`:

```php
filter_var('123', Filter\Filter::VALIDATE_INT);
```

A flag can be specified using `Filter\Flag`:

```php
filter_var(
    '123',
    Filter\Filter::VALIDATE_INT,
    Filter\Flag::ALLOW_OCTAL
);
```

Multiple flags can be combined using their backing integer values:

```php
filter_var(
    '123',
    Filter\Filter::VALIDATE_INT,
    Filter\Flag::ALLOW_OCTAL->value | Filter\Flag::ALLOW_HEX->value
);
```

The existing integer API remains valid:

```php
filter_var('123', FILTER_VALIDATE_INT);
```

### filter\_var\_array()

A filter can be specified directly as an enum:

```php
filter_var_array(
    ['id' => '123'],
    Filter\Filter::VALIDATE_INT
);
```

A filter definition can also use a `Filter\Filter` enum and a `Filter\Flag` enum:

```php
filter_var_array(
    ['id' => '123'],
    [
        'id' => [
            'filter' => Filter\Filter::VALIDATE_INT,
            'flags' => Filter\Flag::ALLOW_OCTAL,
        ],
    ]
);
```

The existing integer constants remain supported:

```php
filter_var_array(
    ['id' => '123'],
    [
        'id' => [
            'filter' => FILTER_VALIDATE_INT,
            'flags' => FILTER_FLAG_ALLOW_OCTAL,
        ],
    ]
);
```

### filter\_input()

A filter can be specified using `Filter\Filter`:

```php
filter_input(
    INPUT_GET,
    'id',
    Filter\Filter::VALIDATE_INT
);
```

A `Filter\Flag` can be supplied as the options argument:

```php
filter_input(
    INPUT_GET,
    'id',
    Filter\Filter::VALIDATE_INT,
    Filter\Flag::ALLOW_OCTAL
);
```

The existing integer constants continue to work:

```php
filter_input(
    INPUT_GET,
    'id',
    FILTER_VALIDATE_INT,
    FILTER_FLAG_ALLOW_OCTAL
);
```

### ''filter\_input\_array()''

A filter can be specified directly as an enum:

```php
filter_input_array(
    INPUT_GET,
    Filter\Filter::VALIDATE_INT
);
```

A filter definition can use both enums:

```php
filter_input_array(
    INPUT_GET,
    [
        'id' => [
            'filter' => Filter\Filter::VALIDATE_INT,
            'flags' => Filter\Flag::ALLOW_OCTAL,
        ],
    ]
);
```

The existing constants remain supported:

```php
filter_input_array(
    INPUT_GET,
    [
        'id' => [
            'filter' => FILTER_VALIDATE_INT,
            'flags' => FILTER_FLAG_ALLOW_OCTAL,
        ],
    ]
);
```

These examples demonstrate that the enums provide a typed alternative to the existing integer constants without requiring existing applications to change their code.

## Backward Incompatible Changes

This RFC does **not** remove or change the existing Filter constants.

Existing code continues to work:

```php
filter_var('123', FILTER_VALIDATE_INT);
```

and:

```php
filter_var(
    '0xff',
    FILTER_VALIDATE_INT,
    FILTER_FLAG_ALLOW_HEX
);
```

Integer arguments remain accepted by all affected APIs.

The enums provide an additional way to specify filters and flags.

## Proposed PHP Version(s)

PHP 8.7

## RFC Impact

### To the Ecosystem

IDEs and static analysis tools may benefit from the more explicit behavior because invalid option values will no longer be silently accepted.

Static analyzers may eventually detect invalid option types and report them before runtime.

### To Existing Extensions

None

### To SAPIs

None

## Open Issues

None at present.

## Future Scope

This RFC is limited to invalid integer-valued `filter` and `flags` options.

## Voting Choices

Primary Vote requiring a 2/3 majority to accept the RFC:

**Vote: Implement Filter\\Filter and Filter\\Flag enums as outlined in the RFC?** — Yes: 0 · No: 0 · Abstain: 0 (closed)

## Patches and Tests

Implementation and tests: <https://github.com/php/php-src/pull/24111>

## Changelog

- 2026-10-07: Revised RFC to reflect the enum implementation in php-src PR #24111.
- 2026-10-03: Initial RFC draft.
