This is an old revision of the document!
PHP RFC: In Operator
- Version: 0.4
- Date: 2015-02-26
- Authors: Niklas Keller me@kelunik.com, Bob Weinand bobwei9@hotmail.com
- Status: Under Discussion
- First Published at: http://wiki.php.net/rfc/in_operator
Introduction
This RFC adds a new in
operator which simplifies contains
checks for strings and arrays. 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. The in
operator makes these checks way more readable. Additionally, it also works for Traversable
.
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.
$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 or integer, it's a simple contains
check, integers are converted to their string representation:
$contains = "foo" in "foobar"; // true $contains = "php" in "foobar"; // false $contains = 0 in "0"; // true $contains = 0 in 100; // true
Note: This is a difference compared to strpos(string, int)
as it uses the string representation instead of searching for the the ordinal value of a character.
Other values than string
, integer
, array
or Traversable
for $haystack
will return false and emit a warning.
If $haystack
is of type string, only string
and integer
are allowed as type of $needle
. Other types will return false and emit a warning.
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:
if (!$input in $validValues) { // ... }
Backward Incompatible Changes
New reserved keyword in
. This affects function, constant, class and method names.
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.
Open Issues
None.
Future Scope
There could be a syntax that allows to check for multiple values at once, e.g.
$contains = ...["foo", "bar"] in ["foo", "baz", "bar"];
Proposed Voting Choices
Requires a 2/3 majority, simple yes / no vote.
Patches and Tests
Rejected Features
Keep this updated with features that were discussed on the mail lists.
Changelog
- v0.4: Removed possibility to check multiple values using an array.