[man]in_array/man takes the item to be searched for as its first argument, and the array in which to search for the item as its second argument. So, you have to be sure that $POST['category'] and $POST['colour'] are both arrays before you pass them to in_array().
On that note, array_shift() takes exactly one argument - the array whose first element is to be removed. If you want to remove the first element of each of two arrays, then you have to call array_shift() twice, i.e., once for each array.
Suppose, $POST['category'] and $POST['colour'] are both arrays. ($POST['category'] && $POST['colour']), on the other hand, must be a boolean value, not an array. As such, your array_search() is problematic, since you are passing to be a scalar value, not an array.
You also wrote:
$_POST['category'][$i] = 0 AND $_POST['colour'][$i] = 0;
I suspect that you want to set the two variables to 0, and in this it works because of the low precedence of AND. On the other hand, this is uncommon usage, and would be better written as:
$_POST['category'][$i] = 0;
$_POST['colour'][$i] = 0;
Your foreach loop problem is also that $_POST['category'] is not guaranteed to be an array. You can check if a variable is an array by using [man]is_array/man.