NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Packagist · #1289 most downloaded on Packagist
PHP Client for Matomo Analytics Tracking API
Last release 2 months ago
03 Aug 2026
Release timing varies
gaps range from 2 weeks to 1.2 years
Some releases are documented
notes for 11 of 32 stable releases
Nothing withdrawn
no release was ever pulled
12 years old
32 releases · first in 2014
Avoid PHP 8.5 deprecation notice when loading the tracker by @sgiehl in #156
Full Changelog: 4.0.0...4.0.1
MatomoTracker.php no longer emits a deprecation notice for the predefined $http_response_header variable on PHP 8.5. PHP reports it at compile time, so it was emitted on every include (#155).One column per quarter.
Attention: this is a major release with breaking changes.
Attention: this is a major release with breaking changes.
Upgrade note — the
false"not known" sentinel is gone. Tracker 3.x let you passfalseto many optional arguments to mean "value not known" (e.g.doTrackEvent($cat, $act, $name, false),addEcommerceItem($sku, $name, $cat, false),setLatitude(false)). Those arguments are now typed (?Tor numeric unions). If your calling code does not usedeclare(strict_types=1)— the usual case for a drop-in tracker — PHP's weak-mode coercion silently turnsfalseinto0/0.0/''instead of raising an error, so such calls now send a value (e_v=0,lat=0, item price0) where 3.x omitted the parameter. Replace everyfalse"not known" argument withnullor simply omit it; passingfalseno longer means "unset".
#[AllowDynamicProperties] attribute. All properties are now declared explicitly, so setting undeclared dynamic properties on a tracker instance is no longer supported (extend MatomoTracker and declare the property instead).declare(strict_types=1) is now enabled and every method has proper parameter and return type hints aligned with how Matomo core handles the corresponding tracking parameters. Passing a value whose type cannot be coerced now throws a TypeError (for example a non-numeric string for a numeric parameter, or any type mismatch when the calling code itself declares strict_types=1). Note that for ordinary (non-strict) callers PHP's weak-mode coercion still applies, so e.g. false becomes 0/'' rather than raising — see the upgrade note above about the removed false sentinel.null instead of the previous false sentinel. For example getUserId(), getUserAgent(), getIp() and getPageviewId() now return null (not false) when no value is set, and doTrackEvent()/getUrlTrackEvent() default the event name and value to null.false to e.g. $tracker->userAgent now throws a TypeError; the attributionInfo property defaults to an empty array instead of false. Subclasses overriding methods with the old untyped signatures may need to be updated to the new signatures.setUserId() now accepts null to de-assign a previously set User ID, as the method documentation always promised (previously the string type hint made that impossible).setUrlReferrer() (and the deprecated setUrlReferer()) accept null to unset the referrer.setCustomTrackingParameter() accepts an array value again (serialized via http_build_query, as the JS tracker does); this restores the pre-3.4.0 behavior for multi-value parameters.setLatitude() / setLongitude() values of 0.0 (equator / prime meridian) are now sent to Matomo. Previously coordinates of exactly zero were silently dropped.0. doTrackGoal() / getUrlTrackGoal() (and the Matomo_/Piwik_ goal helpers) take ?float $revenue = null: null omits revenue (so Matomo uses the goal's configured revenue) while 0.0 now sends revenue=0. Likewise the optional Ecommerce amounts ($subTotal, $tax, $shipping, $discount of doTrackEcommerceOrder() etc.) are ?float = null and only sent when provided, and the required Ecommerce grand total is now always sent (a 0.0 order/cart sends revenue=0). Previously an explicit 0/0.0 was silently omitted for all of these.do* tracking methods now declare a string|bool return type. In bulk mode they return boolean true (previously the value was coerced to the string "1").doTrackSiteSearch() / getUrlTrackSiteSearch() accept ?int $countResults and only send &search_count when a count is provided (previously &search_count=0 was always sent).RuntimeException on request failure (DNS, connection or timeout errors) by default; previously only the cURL transport threw while the stream fallback silently returned false. Call setExceptionsEnabled(false) to make failed requests return false instead, so tracking never breaks the calling application (#105).setRequestTimeout() / setRequestConnectTimeout() if needed._refts, data/customData, cs/charset and the download/link action type passed to getUrlTrackAction()/doTrackAction()), and the visitor ID read from the first-party cookie is validated as a 16-character hexadecimal string.#[\SensitiveParameter] so they are redacted from exception stack traces.token_auth in the request body are now sent as POST; previously the stream transport sent them as GET, so Matomo ignored the token in the body.; (not &), and all incoming Set-Cookie response headers are parsed instead of only the last one; getIncomingTrackerCookie() returns string|false.setAttributionInfo() no longer includes the supplied payload in its exception message (the parameter is also marked #[\SensitiveParameter]).&ca=1 (custom action), so Matomo no longer falls back to recording them as page views if the handling plugin is disabled (#80).cip (override IP) tracking parameter is now URL-encoded like every other value (#151).curl_close() (it was already a no-op on the supported PHP versions) (#149).REQUEST_URI as the source instead of PATH_INFO. With front-controller / path-info routing (e.g. /dir1/page handled by dir1/index.php), PATH_INFO only holds the trailing /page, so the tracker previously recorded a truncated URL; it now records the full requested path. PATH_INFO is no longer used at all (SCRIPT_NAME remains the fallback when REQUEST_URI is unavailable) (#141).phpstan.neon.dist) and the Matomo coding standard via PHP_CodeSniffer (phpcs.xml.dist), both enforced for every pull request through GitHub Actions.setDebugTrackingParameter() (@internal test helper) to append a raw, unvalidated tracking parameter that overrides any built-in parameter of the same name, so integration tests can verify server-side handling of malformed values.setCurlOptions(array) to pass additional cURL options (e.g. CURLOPT_IPRESOLVE, CURLOPT_HTTP_VERSION) for the tracking requests; they are applied after the built-in options (#92). Custom CURLOPT_HTTPHEADER entries are merged with the tracker's own headers rather than replacing them, so adding a header no longer drops the built-in Content-Type (which would otherwise break bulk requests).Full Changelog: 3.4.0...4.0.0
Fix deprecation notice for $http_response_header by @sgiehl in #143
Full Changelog: 3.3.1...3.4.0
$URL is deprecatedMatomoTracker methods have explicitly typesMatomoTracker method return types have strict typesapiUrl for storing API URLAllow setting form factors client hint by @sgiehl in #136
Full Changelog: 3.3.1...3.3.2
Fix: Curl Connection remaining open by @lutdev in #133
fix: Creation of dynamic property MatomoTracker::$currentTs is deprecated by @lutdev in #131
Full Changelog: 3.2.0...3.3.0
MatomoTracker class constants are now explicitly publicMatomoTracker dynamic properties are now explicitly publicadd support for CURLOPT_CONNECTTIMEOUT by @vpapaloukas in #115
Full Changelog: 3.1.3...3.2.0
Add function to set api url by @Vmadmax in #113
Improve PHP 8.2 compatibility (by temporarily allowing dynamic properties)
compatibility improvements for PHP 8.1
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Attention: This version of Matomo PHP Tracker is no longer compatible with Matomo 3.x or earlier
Attention: This version of Matomo PHP Tracker is no longer compatible with Matomo 3.x or earlier
setPerformanceTimings() to set them for page views.setGenerationTime() has been discontinued. The method still exists to not break applications still using it, but it does not have any effect. Please use new page performance metrics as replacement.setPlugins() changed.Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →