Signature
filter_has_var(int $input_type, string $var_name): boolPurpose
filter_has_var() answers one narrow question: does the original input of a given kind contain a variable with this name? It belongs to PHP's filter extension, next to filter_input() and filter_var(). It never reads or validates the value. It only reports whether the name exists, so you can decide whether to go on and validate the value.
Signature
Parameters
$input_type: one of the constantsINPUT_GET,INPUT_POST,INPUT_COOKIE,INPUT_SERVERorINPUT_ENV. It selects which input source to inspect. There is no default, so you must always pass it.$var_name: the name of the variable to look for, for example the query-string keypage. There is no default for this either.
Return value and failure cases
The function returns true when the variable exists in the chosen input source and false when it does not. The result is always a plain boolean, so it is safe in an if condition or a ternary expression. A false result does not mean something went wrong. It only means the name was not found.
The lookup works on the input the request originally arrived with, not on the current contents of the superglobal arrays. This is the most important behavior to remember, and the second example below demonstrates it.
Example 1: checking each input source
The examples run without an incoming web request, so none of these names exist. Each check returns false.
$checks = [
'get' => filter_has_var(INPUT_GET, 'learnphp_missing'),
'post' => filter_has_var(INPUT_POST, 'learnphp_missing'),
'cookie' => filter_has_var(INPUT_COOKIE, 'learnphp_missing'),
];
echo json_encode($checks), PHP_EOL;{"get":false,"post":false,"cookie":false}
Example 2: superglobals are not the same as original input
If your script assigns to $_GET, the new key shows up in isset(), but filter_has_var() still reports the original input and does not see it.
$_GET['page'] = '2';
$result = [
'superglobal' => isset($_GET['page']),
'filter_input_storage' => filter_has_var(INPUT_GET, 'page'),
];
echo json_encode($result), PHP_EOL;{"superglobal":true,"filter_input_storage":false}
This makes the function a reliable way to ask what the client actually sent, even if other code later rewrote $_GET, $_POST or $_COOKIE.
Example 3: a small helper
Wrapping the call in a function gives your code readable intent and keeps the input constant in one place.
function queryParamStatus(string $name): string
{
return filter_has_var(INPUT_GET, $name) ? 'present' : 'absent';
}
$report = [];
foreach (['q', 'page'] as $name) {
$report[$name] = queryParamStatus($name);
}
echo json_encode($report), PHP_EOL;{"q":"absent","page":"absent"}
In a real web request for ?q=php, the same helper would report q as present and page as absent.
Edge cases
- Existence is not content. A request such as
?q=sends the keyqwith an empty string. The name exists, so the check istrueeven though the value is empty. If you need a non-empty value, read it withfilter_input()and validate it afterwards. - Command-line runs. A CLI script or a browser sandbox has no query string, POST body or cookies. Checks against
INPUT_GET,INPUT_POSTandINPUT_COOKIEreturnfalsethere, which makes them easy to test but means you cannot simulate a request by editing superglobals. - Server and environment sources.
INPUT_SERVERandINPUT_ENVdepend on the web server, the SAPI and the process environment. Results can differ between setups, so avoid relying on them in portable code or tests. - Name matching. The name is a plain string key. Array-style input such as
items[]arrives under the keyitems, so check that base name.
Common mistakes
- Expecting it to see runtime changes. Assigning to
$_POST['token']does not makefilter_has_var(INPUT_POST, 'token')returntrue. - Treating
trueas valid. The function says nothing about the value type, range or format. Validation still needsfilter_input()orfilter_var(). - Using the wrong source. A form sent with
method="post"will not be found underINPUT_GET, even if the same name appears in the page URL for a different reason. - Passing a value instead of a name. The second argument is the key to look for, not the data you want to test.
- Using it in unit tests. Because it reads original request input, tests cannot easily control it. Put the call in a thin wrapper and test the code that receives the result.
Related functions
filter_input()fetches a value from an input source and can filter it in the same call.filter_input_array()fetches several inputs at once.filter_var()filters a value that is already in a PHP variable.isset()andarray_key_exists()check the current contents of an array such as$_GET.
Recap
filter_has_var() takes an INPUT_* constant and a name, and returns a boolean telling you whether that name exists in the original input. It does not inspect values, it ignores changes made to superglobals at runtime, and it returns false when nothing was sent. Use it as a quick presence check before you read and validate the data.
Tested examples
$checks = [
'get' => filter_has_var(INPUT_GET, 'learnphp_missing'),
'post' => filter_has_var(INPUT_POST, 'learnphp_missing'),
'cookie' => filter_has_var(INPUT_COOKIE, 'learnphp_missing'),
];
echo json_encode($checks), PHP_EOL;{"get":false,"post":false,"cookie":false}
$_GET['page'] = '2';
$result = [
'superglobal' => isset($_GET['page']),
'filter_input_storage' => filter_has_var(INPUT_GET, 'page'),
];
echo json_encode($result), PHP_EOL;{"superglobal":true,"filter_input_storage":false}
function queryParamStatus(string $name): string
{
return filter_has_var(INPUT_GET, $name) ? 'present' : 'absent';
}
$report = [];
foreach (['q', 'page'] as $name) {
$report[$name] = queryParamStatus($name);
}
echo json_encode($report), PHP_EOL;{"q":"absent","page":"absent"}