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
Traversables 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.