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
.
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.
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.
$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.
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.
$contains = "foo" in "foobar"; // true $contains = "php" in "foobar"; // false
Other expressions than mixed in array|Traversable
or string in string
throw an EngineException
.
It's strict because otherwise something like “foo” in [0]
would pass.
It should have the same precedence as instanceof
, so it's possible to negate it:
if (!$input in $validValues) { // ... }
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.
Next major release, at the time of writing PHP 7.
A T_IN
constant for use with ext/tokenizer has been added.
There could be a syntax that allows to check for multiple values at once, e.g.
$contains = ...["foo", "bar"] in ["foo", "baz", "bar"];
Requires a 2/3 majority. Even if it passes, it will only get merged if the context sensitive lexer gets merged.
Voting started on 2015-03-15 and ends on 2015-03-29.
Keep this updated with features that were discussed on the mail lists.