This is the Developer Changelog for Matomo PHP Tracker. All breaking changes or new features are listed below.
- Loading
MatomoTracker.phpno longer emits a deprecation notice for the predefined$http_response_headervariable on PHP 8.5. PHP reports it at compile time, so it was emitted on every include (#155).
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".
- 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 (extendMatomoTrackerand 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 aTypeError(for example a non-numeric string for a numeric parameter, or any type mismatch when the calling code itself declaresstrict_types=1). Note that for ordinary (non-strict) callers PHP's weak-mode coercion still applies, so e.g.falsebecomes0/''rather than raising — see the upgrade note above about the removedfalsesentinel.- Optional "unset" parameters and their corresponding properties and getters now use
nullinstead of the previousfalsesentinel. For examplegetUserId(),getUserAgent(),getIp()andgetPageviewId()now returnnull(notfalse) when no value is set, anddoTrackEvent()/getUrlTrackEvent()default the event name and value tonull. - All public properties are now natively typed. Assigning a legacy sentinel value such as
falseto e.g.$tracker->userAgentnow throws aTypeError; theattributionInfoproperty defaults to an empty array instead offalse. Subclasses overriding methods with the old untyped signatures may need to be updated to the new signatures. setUserId()now acceptsnullto de-assign a previously set User ID, as the method documentation always promised (previously thestringtype hint made that impossible).setUrlReferrer()(and the deprecatedsetUrlReferer()) acceptnullto unset the referrer.setCustomTrackingParameter()accepts an array value again (serialized viahttp_build_query, as the JS tracker does); this restores the pre-3.4.0 behavior for multi-value parameters.setLatitude()/setLongitude()values of0.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 theMatomo_/Piwik_goal helpers) take?float $revenue = null:nullomitsrevenue(so Matomo uses the goal's configured revenue) while0.0now sendsrevenue=0. Likewise the optional Ecommerce amounts ($subTotal,$tax,$shipping,$discountofdoTrackEcommerceOrder()etc.) are?float = nulland only sent when provided, and the required Ecommerce grand total is now always sent (a0.0order/cart sendsrevenue=0). Previously an explicit0/0.0was silently omitted for all of these. - The
do*tracking methods now declare astring|boolreturn type. In bulk mode they return booleantrue(previously the value was coerced to the string"1"). doTrackSiteSearch()/getUrlTrackSiteSearch()accept?int $countResultsand only send&search_countwhen a count is provided (previously&search_count=0was always sent).- Both transports now consistently throw a
RuntimeExceptionon request failure (DNS, connection or timeout errors) by default; previously only the cURL transport threw while the stream fallback silently returnedfalse. CallsetExceptionsEnabled(false)to make failed requests returnfalseinstead, 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.
- All tracking parameter names and values are now consistently URL-encoded (including
_refts,data/customData,cs/charset and thedownload/linkaction type passed togetUrlTrackAction()/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_authin the request body are now sent asPOST; previously the stream transport sent them asGET, 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 incomingSet-Cookieresponse headers are parsed instead of only the last one;getIncomingTrackerCookie()returnsstring|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_URIas the source instead ofPATH_INFO. With front-controller / path-info routing (e.g./dir1/pagehandled bydir1/index.php),PATH_INFOonly holds the trailing/page, so the tracker previously recorded a truncated URL; it now records the full requested path.PATH_INFOis no longer used at all (SCRIPT_NAMEremains the fallback whenREQUEST_URIis unavailable) (#141).
- 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()(@internaltest 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). CustomCURLOPT_HTTPHEADERentries are merged with the tracker's own headers rather than replacing them, so adding a header no longer drops the built-inContent-Type(which would otherwise break bulk requests).
- Fixed PHP 8.5 deprecation notice
- static
$URLis deprecated - a lot of arguments of
MatomoTrackermethods have explicitly types - a lot of
MatomoTrackermethod return types have strict types
- new private property
apiUrlfor storing API URL
- Support for formFactors client hint parameter, supported as of Matomo 5.2.0
- closed curl connection
- support for PHP versions lower than 7.2
- all
MatomoTrackerclass constants are now explicitly public - all
MatomoTrackerdynamic properties are now explicitly public
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.