Environment
- matomo/matomo-php-tracker: 4.0.0 (and current master, cf976bf)
- PHP: 8.5.4 (CLI, NTS)
What happens
Since PHP 8.5, $http_response_header is deprecated, and the diagnostic is emitted at
compile time — merely including MatomoTracker.php triggers it, without any code
being executed:
$ php -r "include 'vendor/matomo/matomo-php-tracker/MatomoTracker.php';"
Deprecated: The predefined locally scoped $http_response_header variable is deprecated,
call http_get_last_response_headers() instead in .../MatomoTracker.php on line 2419
The offending line is the legacy fallback in sendRequest():
} elseif ($response !== false) {
$responseHeaders = $http_response_header;
}
Why this is a problem
Because it fires on include rather than on use, the notice cannot be avoided by the
function_exists('http_get_last_response_headers') guard, and it cannot be suppressed
with @. Any tool that autoloads the class with error_reporting(E_ALL) and a
throwing error handler aborts. Concrete example — Psalm 6.16.1 crashes while scanning
the package, because it evaluates the class_exists('\MatomoTracker') call in
PiwikTracker.php:17, which triggers the autoloader:
Uncaught RuntimeException: PHP Error: The predefined locally scoped
$http_response_header variable is deprecated ... in .../MatomoTracker.php:2419
#4 .../PiwikTracker.php(17): class_exists('\\MatomoTracker')
(Psalm 6.16.1 crashed due to an uncaught Throwable)
Applications that log deprecations also get one entry per include.
Version 3.4.0 was not affected, because it assigned to the variable before reading it.
Suggested fix
Assigning the variable before reading it silences the compile-time diagnostic while
keeping the PHP < 8.5 fallback working (this is exactly the shape 3.4.0 used):
$responseHeaders = [];
$http_response_header = []; // avoid the PHP 8.5 compile-time deprecation
$response = file_get_contents($url, false, $ctx);
if (function_exists('http_get_last_response_headers')) {
$headers = http_get_last_response_headers();
if (is_array($headers)) {
$responseHeaders = $headers;
}
} elseif ($response !== false) {
$responseHeaders = $http_response_header;
}
Verified on PHP 8.5.4:
function a() { $r = @file_get_contents('http://x'); return $http_response_header; }
// -> Deprecated: The predefined locally scoped $http_response_header variable is deprecated
function b() { $http_response_header = []; $r = @file_get_contents('http://x'); return $http_response_header; }
// -> no diagnostic
Environment
What happens
Since PHP 8.5,
$http_response_headeris deprecated, and the diagnostic is emitted atcompile time — merely including
MatomoTracker.phptriggers it, without any codebeing executed:
The offending line is the legacy fallback in
sendRequest():Why this is a problem
Because it fires on include rather than on use, the notice cannot be avoided by the
function_exists('http_get_last_response_headers')guard, and it cannot be suppressedwith
@. Any tool that autoloads the class witherror_reporting(E_ALL)and athrowing error handler aborts. Concrete example — Psalm 6.16.1 crashes while scanning
the package, because it evaluates the
class_exists('\MatomoTracker')call inPiwikTracker.php:17, which triggers the autoloader:Applications that log deprecations also get one entry per include.
Version 3.4.0 was not affected, because it assigned to the variable before reading it.
Suggested fix
Assigning the variable before reading it silences the compile-time diagnostic while
keeping the PHP < 8.5 fallback working (this is exactly the shape 3.4.0 used):
Verified on PHP 8.5.4: