Variable is used but not definedPHP-W1066
A variable has been used but not defined, which may result in warnings during program execution. This can also cause bugs since the intended usage scope of the variable is not known.
This issue will be raised in the following cases:
- The variable is defined after it is used.
- The variable's definition occurs within an
if
orswitch
statement but is used outside of the condition. - The variable has been destroyed (possibly using
unset()
) but is used again. - An argument to a function is referred to by name after it has already been provided as a positional argument.
$this
is used inside a static method or closure.- Using variables in view/template files, passed from controller or other place.
Bad practice
function greetUser(string $name): string {
echo $greetings . ' ' . $name; // $greetings is not defined yet
$greetings = 'Hello';
}
function greetUser(string $name = '') {
if (is_array($name)) {
$greetings = 'Hello';
}
return $greetings . ' ' . $name; // $greetings is only defined if $name is an array, which is statically impossible due to $name's type hint
}
function greetUser(string $firstName = '', string $lastName = ''): string {
$greetings = 'Hello';
return $greetings . ' ' . $firstName . ' ' . $lastName;
}
greetUser($name, $name = 'Doe'); // $name was not defined before its first use in the first argument, and has been defined in the second argument.
The intent in the above example may have been to use the new named argument syntax introduced in PHP 8. This syntax makes use of the :
operator instead of the =
operator. You can find the documentation for this syntax in the references section.
function greetUser(string $name = '') {
$greetings = 'Hello';
if ($name === '') {
unset($greetings);
}
return $greetings . ' ' . $name; // $greetings may have been destroyed in a previous line, and statically cannot be considered valid
}
greetUser();
class User
{
public static function greet()
{
return $this->getMessage(); // $this will not work inside a static method
}
}
class User
{
public function greet()
{
$message = static function () {
return $this->getMessage(); // $this will not work inside a static closure
};
return $message;
}
}
Using variables in view/template file:
View/template files are basically PHP code fragments. So by themselves, they don’t have enough context available for our analyzer to do its job. So it is discouraged to use analyzer on these files. Use exclude_patterns
to exlude these files/folders from the analysis.
<div>
<!-- Analyzer can't find "message" variable -->
<p><?= $message ?></p>
</div>
Recommended
function greetUser(string $name): string {
$greetings = 'Hello';
echo $greetings . ' ' . $name;
}
function greetUser(string $firstName = '', string $lastName = ''): string {
$greetings = 'Hello';
return $greetings . ' ' . $firstName . ' ' . $lastName;
}
greetUser('John', 'Doe');
function greetUser(string $name = '') {
$greetings = 'Hello';
if ($name === '') {
return $greetings;
}
return $greetings . ' ' . $name;
}
greetUser();
class User
{
public function greet()
{
return $this->getMessage();
}
}
class User
{
public function greet()
{
$message = function () {
return $this->getMessage();
};
return $message;
}
}
Using variables in view/template file:
To make this work, you'll have to add @var
PHPDoc tag throughout the view files. It'll fix the issue causing this error.
/**
* @var string $message
*/
<div>
<!-- Analyzer can't find "message" variable -->
<p><?= $message ?></p>
</div>