I will not make a claim that this is the most efficient method, but it reduces the number of operations considerably compared with && chaining and multiple in_array() calls.
What we'll do is keep a 2-dimensional array of possible win-combinations: rows, columns, diagonals, as sub-arrays. Then in a foreach loop over that 2D array, test the user's current array state against the row combination with array_intersect(). If the entire winning combination is present in the user's array, the result of array_intersect() will be 3, which you can test with count().
Since one match is enough for a win, you can break out of the loop on the first match to declare a win.
$combinations = array(
// Rows
array(0,1,2),
array(3,4,5),
array(6,7,8),
// Columns
array(0,3,6),
array(1,4,7),
array(2,5,8),
// Diagonals
array(0,4,8),
array(2,4,6),
);
// Loop over the array of winners and test array_intersect()
// If 3 values intersect, the full win combination was matched
foreach ($combinations as $combination) {
if (count(array_intersect($combination, $user)) == 3) {
// User wins! Take whatever action necessary...
// Exit the loop
break;
}
}
Here's a demonstration in which 2 of 3 sets for $user are winners: http://codepad.viper-7.com/Mvu0wa
There are algorithmic ways of generating the winning combinations rather than hard-coding them, but there are only eight possible combinations so it isn't that hard, and the point here is the use of array_intersect() to find a subset of the user's current placements.
array_intersect()to compare an array representing a row[0,1,2]with the user's array and verify the output of the intersection hascount() == 3, meaning all 3 were matched. Among the expansive set of PHP array functions there are many which could be used to suit your needs one way or another. Are you planning to keep a list of possible values that constitute a row (simple), or would you want those to be determined algorithmically (a little harder)?$userarray.