PackageTrack
Sign in Get early access

matomo/matomo-php-tracker

PHP Client for Matomo Analytics Tracking API

4.0.1 4.6M downloads/mo #1005 most downloaded on Packagist matomo-org/matomo-php-tracker

What this package is like to depend on

Last release 20 days 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

3 releases in the last 12 months

see the full history below

Release timeline

32 releases · Dec 2014 to Aug 2026
2015 2017 2019 2021 2023 2025
Release Pre-release

Releases

latest 32
  1. 4.0.1 03 Aug 2026
    Release notes

    What's Changed

    • Avoid PHP 8.5 deprecation notice when loading the tracker by @sgiehl in #156

    Full Changelog: 4.0.0...4.0.1

    Open source →
    Release notes

    Fixed

    • Loading 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).
    Open source →
  2. 4.0.0 27 Jul 2026
    Release notes

    Attention: this is a major release with breaking changes.

    Upgrade note — the false "not known" sentinel is gone. Tracker 3.x let you pass false to 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 (?T or numeric unions). If your calling code does not use declare(strict_types=1) — the usual case for a drop-in tracker — PHP's weak-mode coercion silently turns false into 0 / 0.0 / '' instead of raising an error, so such calls now send a value (e_v=0, lat=0, item price 0) where 3.x omitted the parameter. Replace every false "not known" argument with null or simply omit it; passing false no longer means "unset".

    Removed

    • Support for PHP versions lower than 8.1. The tracker now requires PHP 8.1 or newer.
    • The #[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).

    Changed

    • 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.
    • Optional "unset" parameters and their corresponding properties and getters now use 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.
    • All public properties are now natively typed. Assigning a legacy sentinel value such as 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.
    • Goal and Ecommerce revenue amounts now distinguish "not set" from an explicit 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.
    • The 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).
    • Both transports now consistently throw a 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).
    • Lowered the default request timeouts from 600s/300s to 5s/2s so a slow or unreachable Matomo can no longer block the calling page for minutes (#88). Raise them again via setRequestTimeout() / setRequestConnectTimeout() if needed.
    • Bumped the test suite to PHPUnit 10.5.

    Fixed

    • All tracking parameter names and values are now consistently URL-encoded (including _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.
    • Request-failure exceptions no longer include the full request URL (only the target host), so its query string is never surfaced in error messages/logs. The request URL and body are also marked #[\SensitiveParameter] so they are redacted from exception stack traces.
    • Authenticated requests that carry 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.
    • The stream transport now returns the response body for HTTP 4xx/5xx responses (like cURL) instead of turning them into a failure.
    • Bulk tracking uses a more generous request timeout (at least 30s) and no longer discards the queued actions when a batch fails to send, so the batch can be retried.
    • Outgoing tracker cookies are now joined with ; (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]).
    • Event and content tracking requests now send &ca=1 (custom action), so Matomo no longer falls back to recording them as page views if the handling plugin is disabled (#80).
    • The cip (override IP) tracking parameter is now URL-encoded like every other value (#151).
    • No longer calls the deprecated curl_close() (it was already a no-op on the supported PHP versions) (#149).
    • Auto-detection of the tracked page URL now uses 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).

    Added

    • Detect Google-GeminiNotebook as an AI bot by @eldk in #153
    • Add method to track an AI bot request, if the current user agent is a known AI bot by @diosmosis in #148
    • PHPStan static analysis at max level (phpstan.neon.dist) and the Matomo coding standard via PHP_CodeSniffer (phpcs.xml.dist), both enforced for every pull request through GitHub Actions.
    • A greatly expanded unit test suite covering all tracking parameters, cookie handling and request preparation.
    • 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).

    New Contributors

    • @eldk made their first contribution in #153

    Full Changelog: 3.4.0...4.0.0

    Open source →
    Release notes

    Attention: this is a major release with breaking changes.

    Upgrade note — the false "not known" sentinel is gone. Tracker 3.x let you pass false to 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 (?T or numeric unions). If your calling code does not use declare(strict_types=1) — the usual case for a drop-in tracker — PHP's weak-mode coercion silently turns false into 0 / 0.0 / '' instead of raising an error, so such calls now send a value (e_v=0, lat=0, item price 0) where 3.x omitted the parameter. Replace every false "not known" argument with null or simply omit it; passing false no longer means "unset".

    Removed

    • Support for PHP versions lower than 8.1. The tracker now requires PHP 8.1 or newer.
    • The #[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).

    Changed

    • 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.
    • Optional "unset" parameters and their corresponding properties and getters now use 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.
    • All public properties are now natively typed. Assigning a legacy sentinel value such as 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.
    • Goal and Ecommerce revenue amounts now distinguish "not set" from an explicit 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.
    • The 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).
    • Both transports now consistently throw a 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).
    • Lowered the default request timeouts from 600s/300s to 5s/2s so a slow or unreachable Matomo can no longer block the calling page for minutes (#88). Raise them again via setRequestTimeout() / setRequestConnectTimeout() if needed.
    • Bumped the test suite to PHPUnit 10.5.

    Fixed

    • All tracking parameter names and values are now consistently URL-encoded (including _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.
    • Request-failure exceptions no longer include the full request URL (only the target host), so its query string is never surfaced in error messages/logs. The request URL and body are also marked #[\SensitiveParameter] so they are redacted from exception stack traces.
    • Authenticated requests that carry 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.
    • The stream transport now returns the response body for HTTP 4xx/5xx responses (like cURL) instead of turning them into a failure.
    • Bulk tracking uses a more generous request timeout (at least 30s) and no longer discards the queued actions when a batch fails to send, so the batch can be retried.
    • Outgoing tracker cookies are now joined with ; (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]).
    • Event and content tracking requests now send &ca=1 (custom action), so Matomo no longer falls back to recording them as page views if the handling plugin is disabled (#80).
    • The cip (override IP) tracking parameter is now URL-encoded like every other value (#151).
    • No longer calls the deprecated curl_close() (it was already a no-op on the supported PHP versions) (#149).
    • Auto-detection of the tracked page URL now uses 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).

    Added

    • PHPStan static analysis at max level (phpstan.neon.dist) and the Matomo coding standard via PHP_CodeSniffer (phpcs.xml.dist), both enforced for every pull request through GitHub Actions.
    • A greatly expanded unit test suite covering all tracking parameters, cookie handling and request preparation.
    • 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).
    Open source →
  3. 3.4.0 20 Dec 2025
    Release notes

    What's Changed

    • Strict types for arguments and return types by @lutdev in #135
    • Exclude development resources from dist archive by @mbrodala in #138
    • Fix deprecation notice for $http_response_header by @sgiehl in #143
    • Declare supported PHP versions explicitly and run tests on all supported versions by @gsteel in #147
    • Fix: Not possible to create multiple Piwik tracker instances having different API urls by @lutdev in #145

    New Contributors

    Full Changelog: 3.3.1...3.4.0

    Open source →
    Release notes

    Changed

    • Fixed PHP 8.5 deprecation notice
    • static $URL is deprecated
    • a lot of arguments of MatomoTracker methods have explicitly types
    • a lot of MatomoTracker method return types have strict types

    Added

    • new private property apiUrl for storing API URL
    Open source →
  4. 3.3.2 09 Oct 2024
    Release notes

    What's Changed

    • Allow setting form factors client hint by @sgiehl in #136

    Full Changelog: 3.3.1...3.3.2

    Open source →
    Release notes

    Changed

    • Support for formFactors client hint parameter, supported as of Matomo 5.2.0
    Open source →
  5. 3.3.1 21 May 2024
    Release notes

    What's Changed

    • Fix: Curl Connection remaining open by @lutdev in #133

    Full Changelog: 3.3.0...3.3.1

    Open source →
    Release notes

    Fixed

    • closed curl connection
    Open source →
  6. 3.3.0 17 May 2024
    Release notes

    What's Changed

    • feat: remove composer.lock by @Chris53897 in #117
    • fix: wrong method description by @revoltek-daniel in #125
    • feat: Functions to get and set the page view id manually by @EPNW-Eric in #126
    • feat: default folder structure, allow phpunit 10 by @Chris53897 in #116
    • fix: Check for cURL error before throwing exception in sendRequest method by @mzaman in #130
    • fix: Creation of dynamic property MatomoTracker::$currentTs is deprecated by @lutdev in #131
    • feat: Drop support of older php versions by @lutdev in #132

    New Contributors

    Full Changelog: 3.2.0...3.3.0

    Open source →
    Release notes

    Removed

    • support for PHP versions lower than 7.2

    Changed

    • all MatomoTracker class constants are now explicitly public
    • all MatomoTracker dynamic properties are now explicitly public
    Open source →
  7. 3.2.0 24 Mar 2023
    Release notes

    What's Changed

    New Contributors

    Full Changelog: 3.1.3...3.2.0

    Open source →
  8. 3.1.3 07 Mar 2023
    Release notes

    What's Changed

    New Contributors

    Full Changelog: 3.1.2...3.1.3

    Open source →
  9. 3.1.2 18 Jan 2023
    Release notes
    • Improve PHP 8.2 compatibility (by temporarily allowing dynamic properties)
    Open source →
  10. 3.1.1 07 Dec 2022
    Release notes
    • compatibility improvements for PHP 8.1 (#108)
    • added method to disable bulk tracking (#109)
    • added tracking methods for upcoming premium feature (#110)
    Open source →
  11. 3.1.0 04 Jul 2022

    Nothing published for this version

  12. 3.0.4 15 Nov 2021

    Nothing published for this version

  13. 3.0.3 15 Nov 2021

    Nothing published for this version

  14. 3.0.2 14 Nov 2021

    Nothing published for this version

  15. 3.0.1 19 May 2021

    Nothing published for this version

  16. 3.0.0 21 Nov 2020
    Release notes

    Attention: This version of Matomo PHP Tracker is no longer compatible with Matomo 3.x or earlier

    • Support for new page performance metrics (added in Matomo 4) has been added. You can use setPerformanceTimings() to set them for page views.
    • Setting page generation time using 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.
    • Sending requests using cURL will now throw an exception if an error occurs in a request.
    • Matomo does not longer support tracking of these browser plugins: Gears, Director. Therefor the signature of setPlugins() changed.
    • Implementation of ecommerce views changed from custom variables to raw parameters
    • It is now possible to configure cookie options for Secure, HTTPOnly and SameSite.
    • Add method setRequestMethodNonBulk() to allow (non bulk) POST requests.
    Open source →
  17. 2.0.3 14 Jan 2020

    Nothing published for this version

  18. 2.0.2 14 Jan 2020

    Nothing published for this version

  19. 2.0.1 02 Jan 2020

    Nothing published for this version

  20. 2.0.0 01 Jan 2020

    Nothing published for this version

  21. 1.5.2 23 Dec 2019

    Nothing published for this version

  22. 1.5.1 06 Nov 2019

    Nothing published for this version

  23. 1.5.0 06 Nov 2019

    Nothing published for this version

  24. 1.4.1 12 Oct 2018

    Nothing published for this version

  25. 1.4.0 09 Nov 2017

    Nothing published for this version

  26. 1.3.0 08 Jun 2017

    Nothing published for this version

  27. 1.2.0 18 Feb 2017

    Nothing published for this version

  28. 1.1.0 27 Dec 2016

    Nothing published for this version

  29. 1.0.3 13 Jul 2016

    Nothing published for this version

  30. 1.0.2 12 Jan 2016

    Nothing published for this version

  31. 1.0.1 11 Nov 2015

    Nothing published for this version

  32. 1.0.0 18 Dec 2014

    Nothing published for this version

Every package, every release, already written down.

The archive is open and free. Watching your own project is what we are building next.

Browse the archive