filter_has_var
Checks whether a variable was actually sent in the given input type, such as GET, POST or COOKIE.
filter_has_var(int $input_type, string $var_name): bool- Added in PHP 5.2.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$input_type | int | One of INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER or INPUT_ENV. |
$var_name | string | Name of the variable to check for. |
Return value
boolReturns true if the variable exists in the raw input of the given type, false otherwise.
Errors
Passing an input type that is not a valid INPUT_* constant raises a ValueError.
Changelog
- PHP 8.0INPUT_REQUEST and INPUT_SESSION were removed; they were never implemented and passing them now fails.
filter_has_var() answers one narrow question: was this key present in the request PHP actually received? It does not read the superglobal array. It reads the raw data the SAPI handed to PHP when the request started, before any of your code ran.
When to reach for it
Use it when "the field was submitted but empty" and "the field was never submitted" mean different things. An unchecked HTML checkbox sends nothing at all; a cleared text input sends an empty string. filter_has_var(INPUT_POST, 'newsletter') tells the two apart, and it keeps telling them apart even if earlier code has already written to $_POST.
That is also the main reason to prefer it over isset(): it is immune to anything your own framework, router or legacy include has stuffed into the superglobals. If you want the opposite — to see the array as it is right now, including your own modifications — use isset() or array_key_exists() instead.
What trips people up
An empty value still counts as present, so filter_has_var() returns true for ?page=. It is a presence check, never a "has a usable value" check. Pair it with filter_input() when you need the value validated too.
Example
<?php
// Assume the browser requested: /search.php?q=php&page=
var_dump(filter_has_var(INPUT_GET, 'q')); // bool(true)
var_dump(filter_has_var(INPUT_GET, 'page')); // bool(true) present but empty
var_dump(filter_has_var(INPUT_GET, 'sort')); // bool(false) never sent
// The raw input is what counts, not the live array:
$_GET['injected'] = 1;
var_dump(isset($_GET['injected'])); // bool(true)
var_dump(filter_has_var(INPUT_GET, 'injected')); // bool(false)When to use it
- Tell an unchecked checkbox (never submitted) apart from a cleared text field (submitted as an empty string).
- Decide whether to apply a default in a search form, without a modified $_GET fooling the check.
- Detect whether a legacy include has been injecting values into $_POST behind your back.
Frequently asked questions
What is the difference between filter_has_var and isset?
isset() looks at the current contents of the superglobal, including anything your own code wrote into it; filter_has_var() looks at the raw data the SAPI gave PHP at the start of the request. If nothing modifies the superglobals, the two agree.
Does filter_has_var return true for an empty value?
Yes. It is a presence check only, so ?page= makes filter_has_var(INPUT_GET, 'page') return true. Use filter_input() or a strict comparison if you also need the value to be non-empty.
Why does filter_has_var always return false on the command line?
The CLI SAPI has no GET, POST or COOKIE input to register, so those input types are empty. filter_has_var only works meaningfully inside a real HTTP request.
More examples
Checkbox submitted vs. never submitted
The output shows that <code>bio</code> counts as submitted even though its value is an empty string, while the unchecked <code>newsletter</code> checkbox is absent entirely. Only the second case should fall back to a stored default.
<?php
// POST body: name=Bob&bio=
$fields = ['name', 'bio', 'newsletter'];
foreach ($fields as $field) {
$sent = filter_has_var(INPUT_POST, $field);
echo $field, ': ', $sent ? 'submitted' : 'absent', "\n";
}
// name: submitted
// bio: submitted
// newsletter: absentGuarding a filter_input() call
<code>filter_input()</code> returns <code>null</code> for a missing key and <code>false</code> for a value that fails the filter. Checking presence first lets you report "you left this blank" separately from "that is not an email address".
<?php
// GET /profile.php?email=
if (!filter_has_var(INPUT_GET, 'email')) {
echo "No email field in the request\n";
} else {
$email = filter_input(INPUT_GET, 'email', FILTER_VALIDATE_EMAIL);
var_dump($email); // bool(false) — sent, but not a valid address
}
Discussion