Google Analytics PHP cookie parser

Maio 18, 2010 | Por

Google Analytics collects data using first-party cookies who are stored on our browsers. I’ve programmed a PHP class we can use to read Google Analytics __utma and __utmz cookies. This class can be used to easily integrate this cookie data into proprietary systems like CRM, ERP, Helpdesks, etc.

  • __utma (expires 2 years after being defined) – visitor dataThis cookie is written on your first visit to the website. In case you erase it its created again. Its used for the Unique Visitors calculation and is updated on every pageview.
  • __utmz (expires 6 months after being defined) – campaign dataThis cookie stores informations on how the user got to our website: referrer, direct (none), organic or a campaign such as a newsletter. (since you tag it correctly using the URL Builder). This cookie is overwritten every time you visit the website.

The Google Analytics Cookie Parser allows you to obtain some data contained in this cookies in a human readable format. For example, you can see how you got here by visiting: http://joaocorreia.pt/example.php.

  • Campaign source
  • Campaign name
  • Campaign medium
  • Campaign content
  • Campaign term
  • Date of first visit
  • Date of previous visit
  • Date of current visit
  • Times visited
  • Pages viewed


Download the latest version of Google Analytics PHP cookie parser from Github.
https://github.com/joaolcorreia/Google-Analytics-PHP-cookie-parser

example.php

<?

require("class.gaparse.php");

$aux = new GA_Parse($_COOKIE);

echo "Campaign source: ".$aux->campaign_source."<br />";
echo "Campaign name: ".$aux->campaign_name."<br />";
echo "Campaign medium: ".$aux->campaign_medium."<br />";
echo "Campaign content: ".$aux->campaign_content."<br />";
echo "Campaign term: ".$aux->campaign_term."<br />";

echo "Date of first visit: ".$aux->first_visit."<br />";
echo "Date of previous visit: ".$aux->previous_visit."<br />";
echo "Date of current visit: ".$aux->current_visit_started."<br />";
echo "Times visited: ".$aux->times_visited."<br />";
echo "Pages viewed current visit: ".$aux->pages_viewed."<br />";

?>
<script>

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-279423-28']); //279423-28
_gaq.push(['_trackPageview']);
_gaq.push(['_trackPageLoadTime']);

(function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();

</script>

class.gaparse.php

<?php
////////////////////////////////////////////////////
// GA_Parse - PHP Google Analytics Parser Class
//
// Version 1.0 - Date: 17 September 2009
// Version 1.1 - Date: 25 January 2012
// Version 1.2 - Date: 21 April 2012
//
// Define a PHP class that can be used to parse
// Google Analytics cookies currently with support
// for __utmz (campaign data) and __utma (visitor data)
//
// Author: Joao Correia - http://joaocorreia.pt
//
// License: LGPL
//
////////////////////////////////////////////////////

class GA_Parse
{

  var $campaign_source;    		// Campaign Source
  var $campaign_name;  			// Campaign Name
  var $campaign_medium;    		// Campaign Medium
  var $campaign_content;   		// Campaign Content
  var $campaign_term;      		// Campaign Term

  var $first_visit;      		// Date of first visit
  var $previous_visit;			// Date of previous visit
  var $current_visit_started;	// Current visit started at
  var $times_visited;			// Times visited
  var $pages_viewed;			// Pages viewed in current session

  function __construct($_COOKIE) {
	   // If we have the cookies we can go ahead and parse them.
	   if (isset($_COOKIE["__utma"]) and isset($_COOKIE["__utmz"])) {
	       $this->ParseCookies();
       }

  }

  function ParseCookies(){

  // Parse __utmz cookie
  list($domain_hash,$timestamp, $session_number, $campaign_numer, $campaign_data) = split('[\.]', $_COOKIE["__utmz"],5);

  // Parse the campaign data
  $campaign_data = parse_str(strtr($campaign_data, "|", "&"));

  $this->campaign_source = $utmcsr;
  $this->campaign_name = $utmccn;
  $this->campaign_medium = $utmcmd;
  if (isset($utmctr)) $this->campaign_term = $utmctr;
  if (isset($utmcct)) $this->campaign_content = $utmcct;

  // You should tag you campaigns manually to have a full view
  // of your adwords campaigns data.
  // The same happens with Urchin, tag manually to have your campaign data parsed properly.

  if (isset($utmgclid)) {
    $this->campaign_source = "google";
    $this->campaign_name = "";
    $this->campaign_medium = "cpc";
    $this->campaign_content = "";
    $this->campaign_term = $utmctr;
  }

  // Parse the __utma Cookie
  list($domain_hash,$random_id,$time_initial_visit,$time_beginning_previous_visit,$time_beginning_current_visit,$session_counter) = split('[\.]', $_COOKIE["__utma"]);

  $this->first_visit = date("d M Y - H:i",$time_initial_visit);
  $this->previous_visit = date("d M Y - H:i",$time_beginning_previous_visit);
  $this->current_visit_started = date("d M Y - H:i",$time_beginning_current_visit);
  $this->times_visited = $session_counter;

  // Parse the __utmb Cookie

  list($domain_hash,$pages_viewed,$garbage,$time_beginning_current_session) = split('[\.]', $_COOKIE["__utmb"]);
  $this->pages_viewed = $pages_viewed;

 // End ParseCookies
 }

// End GA_Parse
}

?>
  • Pingback: Avaliar o sucesso da minha campanha de marketing online - Google Analytics | João Correia

  • Pingback: Avaliar o sucesso das campanhas marketing online | Marketing Online Portugal

  • Deyan Kyosev

    Hi, this is a great article, but where $utmcsr, $utmccn, $utmcmd, $utmctr, $utmcct are initialized?

  • http://www.facebook.com/joaolcorreia João Correia

    Hello Deyan, 
    I get those variables from parse_str on line 43, I don’t initialize them.

  • Pingback: Avaliar o sucesso das campanhas de marketing online | Marketing Online Portugal

  • Joe

    Has anybody figure out how to make this work with Google Adwords.

  • http://joaocorreia.pt João Correia

    Hello Joe, If you want to use the GA cookie parser you have to manually tag your URLs with URL Builder.
    http://www.google.com/support/analytics/bin/answer.py?answer=55578

  • Webimerge

    Hi I want to display whether the user came from a paid or organic link can I you give me some advice on this?

  • Anónimo

    Thank you by sharing your code, I used it and worked fine!

  • Nei Rauni Santos

    It would be great if you update your code in order to avoid notices in recent php versions..

    Notice: Undefined variable: utmgclid on /lib/gaparse.class.php on line 59

    Thank you,

  • http://joaocorreia.pt João Correia

    Hello Nei,

    I’ve just fixed this.

    Thanks

  • http://joaocorreia.pt João Correia

    Hello, you can see it right away on Campaign medium. Install the class and test its pretty straightforward !

  • Anónimo

    Thanks for the inspiration!
    Bug report: 
    list($domain_hash,$timestamp, $session_number,$campaign_numer, $campaign_data) = split(‘[.]‘, $this->utmz); 
    should be 
    list($domain_hash,$timestamp, $session_number,$campaign_numer, $campaign_data) = split(‘[.]‘, $this->utmz, 5); 
    because keyword may contain periods.
    Cheers!

  • Dan

    Hello. Thank you for sharing a very nice script. One issue I found is when parsing utmcsr you lose some information. For example: if utmcsr= “answers.yahoo.com”, then result is just “answers”. Otherwise I have to say this works great!

  • http://jeffjudge.com Jeff Judge

    Thanks, this script was very helpful!

  • http://joaocorreia.pt João Correia

    Bug fixed ! I also fixed some error Notices.Thank you! 

  • http://joaocorreia.pt João Correia

    Hello Dan ! Its solved now, thanks to timhas !

  • http://joaocorreia.pt João Correia

    Thanks Jeff. I updated it just now with minor fixes!

  • http://twitter.com/vladblagi Vladimir Blagojevic

    Hi, 

    thanks so much for sharing, it works great. 

    There is a deprecation warning for PHP > 5.3 for the split() function. These lines solve it (replacing split with explode): 

    46:  list($domain_hash,$timestamp, $session_number, $campaign_numer, $campaign_data) = explode(‘.’, $_COOKIE["__utmz"]);
    70:   list($domain_hash,$random_id,$time_initial_visit,$time_beginning_previous_visit,$time_beginning_current_visit,$session_counter) = explode(‘.’, $_COOKIE["__utma"]);
    79:   list($domain_hash,$pages_viewed,$garbage,$time_beginning_current_session) = explode(‘.’, $_COOKIE["__utmb"]);

    Best 
    Vlad

  • http://twitter.com/vladblagi Vladimir Blagojevic

    Hi, 

    Thanks so much for posting this code, very useful. 

    A small question, I’m getting Undefined variable: utmccn. Do you know why this could be?

    Best 
    Vlad 

  • http://joaocorreia.pt João Correia

    Problem is it stops working with . on variables !

  • Udarajunk

     Hi Joao,

    I tried this on IE7 , but it doesnt update campaign term etc. For an example, if I go to google and on IE7,8 and 9 and type “keyword one” and land on the website, your script shows campaign term as “keyword one” and If I go to google again and type “keyword two” and land on  your website, it still shows “keyword one” in the cookie, it doesn’t get updated. Is there anyway we can clear the cookie once a user visits the site after recording their cookie information?

  • Andrós

    for PHP > 5.3: Use ‘preg_split’ instead ‘split’. Works perfect!

  • Richard

    Hi, great job! Your script will likely be very useful to me.

    I have only tried your example in Firefox, and when I try in Google Chrome it’s not working. Works ok for IE and Safari, I didn’t try Opera.

  • Andrey

    amazing script, works well, but is there any way to send this code via contact form when client/site visitor fills out and sends contact form? I’m new to php and would appreciate any help and/or direction with that.
     Thank you.

  • ph_bueno

    Hello João!
    I’m using the v1.0 and getting some errors, when saving in the database:
    “SQLSTATE[22021]: Character not in repertoire: 7 ERROR: invalid byte sequence for encoding “UTF8″: 0xe1″
    I’ll update to the v1.2, and if the error persist, I come back =)
    And thanks, the script is very usefull

  • http://www.facebook.com/anahmani Ari Nahmani

    Amazing script! Any chance you can pull other data that would be valuable in a contact form? Like landing page or time-on-site? 

    Ari

  • http://twitter.com/joaocorreia Joao Correia ⚡

    Hello Andrey, of course that’s what this simple class was designed for. Just look for a simple contact form script using PHP. On the PHP script that sends the e-mail just include the variables on example.php in your email body  (without echo) and you’re done.Good luck !

  • http://twitter.com/joaocorreia Joao Correia ⚡

    Hello Ari, 

    Yes thats possible. My goal is just to provide the cookie data, you can then do some calculations in order to get time on site, time to convert, landing page, browser, etc. You just have to include more variables on your PHP.Thanks.

  • http://twitter.com/joaocorreia Joao Correia ⚡

    Hi,

    Sorry, can’t help you with this one :( . This seams more like an SQL problem.

  • http://www.facebook.com/profile.php?id=1072555166 Jay Mishra

    Hi,
    In Chrome, utmctr is not saved in cookie. So it return utmctr =(not provided) while it works for IE8 and FF. Can u please me guide on it?

  • http://www.facebook.com/koyot007 Cesar Miggiolaro

    Correia,

    I would suggest an improvement in the code.

        if (isset($utmgclid)) {
          $this->campaign_source = “google”;
          $this->campaign_medium = “cpc”;
          $this->campaign_term = $utmctr;
        }

    removing these lines

    $this->campaign_name = “”;
    $this->campaign_content = “”;

    these lines interferes with the capture of campaign  gclid + utmccn and utmcct

    Thanks

  • Chris

    Really GREAT SCRIPT! I although tried to get the landing page, but did not succeed at all… any chance you can help out ?

  • droz1742

    Great job Joao!

    Any chance at grabbing the matched search query for clicks that come from google cpc?

    Also, landing page would be great. Thanks!

  • http://twitter.com/joaocorreia Joao Correia ⚡

    Hi,

    You can’t grab the matched search query, thats only available in GA because its integrated with AdWords through gclid, at least when using auto-tagging. If you use manual tagging the keyword can be captured if you specify utm_term. Take a look at URL builder to generate the URL with the campaign variables.

  • http://twitter.com/joaocorreia Joao Correia ⚡

    Hi,

    Well that’s odd, can you check the cookies in the browser and see if they changed ? Because if they did, the parser should grab them.

  • http://twitter.com/joaocorreia Joao Correia ⚡

    The (not provided) is related to the use of https by google search when you are authenticated. Unfortunately they stopped sending the keywords !

  • wissem

    Is there someone who could explain why it does not work the first time, when I refresh page it works

  • wissem

    Is there someone who could explain why it does not work the first time, when I refresh page it works

  • http://twitter.com/joaocorreia Joao Correia ⚡

    Hi Wissem,

    Because on the first page of the first visit the PHP gets processed before you even have Google Analytics cookies for that domain, thats why it doesn’t show up on the first page.

  • wissem

    is there a solution to solve the problem ????

  • http://twitter.com/joaocorreia Joao Correia ⚡

    If you want to capture the variables on the page you land without generating another pageview, maybe the only solution might be to use a cookie parser in JS.

  • Can

    Any idea how to get browser name using analytics cookies?

  • http://twitter.com/joaocorreia Joao Correia ⚡

    Hi Can,

    If you need the user agent you can get it with the php variable:

    $_SERVER['HTTP_USER_AGENT']

    Happy coding!

  • http://www.facebook.com/roger.webb.357 Roger Webb

    Hey Everyone,

    I committed a couple of changes to this and have opened a Pull Request with Joao. The “split” function has been deprecated, so I replaced calls to it with “preg_split”.

    I also changed the date/time fields from string to DateTime. The string that was being used threw an Exception when passed into DateTime. While this is a backward-compatibility break, I thought it would be worthwhile.

    As always, I’m open to any suggestions if anyone thinks there is a better way to improve on this. My github repo is here:

    https://github.com/RogerWebb/Google-Analytics-PHP-cookie-parser

    Thanks Joao, this has definitely proven useful.

  • http://twitter.com/joaocorreia Joao Correia ⚡

    Thank you Roger ! Your contribution was added ! :-)

  • Yanni

    Has anybody configured a good cookie parser in JS?

  • anagie

    @twitter-13015792:disqus is it possible to capture the Campaign Content if the referring URL’s path is dynamic such as `http://www.example.com/?p=15592` it seems that dynamic URL path’s are not captured in the Analytics cookie. Is there any way to get the path?

    Thanks
    Peter

  • James Wagoner

    Any reason why I have to pass $_COOKIE when I instantiate the class? I took that argument out of the construct method and still functioned the same.

  • sergio

    I’ve been using this script for years, but it seems that with the new ‘Universal Analytics’ it doesn’t work anymore. Will the script be updated, or should I stick with classic analytics?

  • kitchin

    Hola, breakage in PHP version 5.4 unfortunately. Here is the fix: http://wordpress.org/support/topic/incompatible-with-php-54x

    PHP did not deprecate the feature in 5.3, just made it a fatal error in 5.4.
    “Fatal error: Cannot re-assign auto-global variable _COOKIE in…”

  • http://joaocorreia.pt/ João Correia

    With the new Universal GA the information is stored with Google instead of cookies. This script will not work.
    The fix would be to create the cookies manually just for attribution purpose.

  • kitchin

    It may be a parameter so you can synthesize the cookie string if switching between domains or SSL/non-SSL. Anyway, the parameter needs to be changed to ‘$cookie’, or any name other than a superglobal, due to changes in PHP 5.4, see http://www.php.net/manual/en/migration54.incompatible.php and my post above with a link to fixed code. Fatal error otherwise.