# RFC: In Operator

- Status: Declined
- Authors: Niklas Keller me@kelunik.com, Bob Weinand bobwei9@hotmail.com
- Date: 2015-03-15
- Version: 0.5.1
- Original: https://wiki.php.net/rfc/in_operator
- Page: https://externals.io/rfc/in_operator
- 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

### Introduce the in operator? (closed)

Yes: 21 · No: 26

Voters: aharvey (No), ajf (No), ben (Yes), bishop (No), brandon (Yes), bwoebi (Yes), damz (No), danack (No), duodraco (Yes), eliw (Yes), fa (No), fibbarth (Yes), galvao (No), indeyets (Yes), irker (No), jedibc (Yes), jwage (Yes), kinncj (No), klaussilveira (Yes), leigh (No), lstrojny (Yes), mbeccati (No), mike (No), mj (No), ocramius (No), patrickallaert (No), pauloelr (Yes), philstu (Yes), pollita (No), ralphschindler (No), ramsey (No), rdohms (Yes), rmf (Yes), salathe (No), santiagolizardo (Yes), sebastian (No), seld (Yes), stas (No), stelianm (No), subjective (No), theseer (Yes), till (Yes), timo (No), wiesemann (Yes), yohgaki (No), yunosh (Yes), zeev (No)

## Discussions on the mailing list

- [\[RFC\]\[Discussion\] In Operator](https://externals.io/message/83293.md) — started on 2015-02-20, 11 messages
- [\[RFC\]\[DISCUSSION\] Context Sensitive Lexer v0.4](https://externals.io/message/83735.md) — started on 2015-02-25, 1 messages
- [\[RFC\]\[PRE-VOTE\] In Operator](https://externals.io/message/84793.md) — started on 2015-03-15, 17 messages
- [\[RFC\]\[VOTE\] In Operator](https://externals.io/message/84885.md) — started on 2015-03-15, 12 messages

---

## Introduction

This RFC adds a new `in` operator which simplifies `contains` checks for strings and arrays. The `in` operator makes these checks way more readable and lowers the cognitive load. Additionally, it also works for `Traversable`.

## Motivation

Checking if a specific input in an allowed range of value is a very common check in web application, therefore this operator simplifies those checks (and besides makes them a little bit faster). Currently, we have to use `in_array($needle, $haystack, true)` or `strpos($haystack, $needle) !== false`. These functions have a inconsistent parameter order, so it's hard to remember which is the right one for each. Additionally, omitting the third parameter for `in_array` is very common which led to security vulnerabilities in the past.

## Proposal

Add a new operator `(expr1) in (expr2)`. It checks whether `expr2` contains `expr1`.

It uses strict comparison (`===`) for array values / instances of `Traversable` and doesn't search recursively.

```php
$contains = "foo" in ["a", "b", "c"]; // false
$contains = "foo" in ["foo", "bar"]; // true
$contains = "foo" in [["foo"], ["bar"]]; // false
$contains = "0e0" in ["0"]; // false, because of strict comparison
$contains = 0 in ["0"]; // false, because of strict comparison
 
$contains = ["foo"] in [["foo"], ["bar"]]; // true
$contains = ["foo"] in ["foo"]; // false
```

`Traversable`s are only iterated until there's a match.

```php
function gen () {
    yield "foo";
    yield "bar";
    // code below here wouldn't be executed if "bar" matches
    // because it stops if there's a match.
}
 
$contains = "bar" in gen(); // true
$contains = "baz" in gen(); // false
```

If `$haystack` is a string, it's a simple `contains` check.

```php
$contains = "foo" in "foobar"; // true
$contains = "php" in "foobar"; // false
```

Other expressions than `mixed in array|Traversable` or `string in string` throw an `EngineException`.

### Why strict?

It's strict because otherwise something like `“foo” in [0]` would pass.

### Precedence

It should have the same precedence as `instanceof`, so it's possible to negate it:

```php
if (!$input in $validValues) {
    // ...
}
```

## Backward Incompatible Changes

New reserved keyword `in`. This affects function, constant and class, **but not** class constant and method names, because it depends on the context sensitive lexer being merged.

## Proposed PHP Version(s)

Next major release, at the time of writing PHP 7.

## RFC Impact

### New Constants

A `T_IN` constant for use with ext/tokenizer has been added.

## Future Scope

There could be a syntax that allows to check for multiple values at once, e.g.

```php
$contains = ...["foo", "bar"] in ["foo", "baz", "bar"];
```

## Votes

Requires a 2/3 majority. Even if it passes, it will *only* get merged if the [context sensitive lexer](https://externals.io/rfc/context_sensitive_lexer) gets merged.

**Vote: Introduce the in operator?** — Yes: 21 · No: 26 (closed)

Voting started on 2015-03-15 and ends on 2015-03-29.

## Patches and Tests

- <https://github.com/php/php-src/pull/1121>

## Rejected Features

Keep this updated with features that were discussed on the mail lists.

## Changelog

- v0.5: Removed integer support, so the strictness is consistent.
- v0.4: Removed possibility to check multiple values using an array.
