This answer is an explanation of the shorthand type casting, from comments, as it's easier to read it as an answer than as a set of comments.
Your code:
filter_var($_POST["user_id"], FILTER_VALIDATE_INT) !== false.
This is a long winded way of ensuring that POSTed data is integer. It has issues, because POST data is always cast as a string.
$_POST["user_id"] = (int)$_POST["user_id"];
Is much easier to read and shorter to type, and this forces the data to be the integer type. This will competely solve your security risk if putting non-integer data into an integer placement in your SQL.
This utalises PHP Type Juggling which it is well worth reading up on.
While the above code will solve your security aspect, it will raise other overlap issues because any string can be casted to an integer, but the cast will return 0 if the string doesn't start with an integer value.
Example:
$string = "hello";
print (int)$string; // outputs 0;
$string = "27hello";
print (int)$string; // outputs 27;
$string = true;
print (int)$string; // outputs 1;
$string = "";
print (int)$string; // outputs 0;
So, overall I would suggest the following line to ensure your given POST value is a correct integer:
if (strcmp((int)$_POST['value'], $_POST['value']) == 0){
/// it's ok!
}
Please see this answer for further details as well as this PHP manual page.