Tracking the user’s browsing history with PHP

March 7, 2008 – 2:25 pm Tags: ,

There are various reasons for tracking what an user does:

  • Keeping track of the refering page for forms, so they can be sent back to where they came from
  • Tracking usage behavior for statistics
  • etc.

Let’s look at how we could implement a simple user tracker in PHP with Zend Framework. I’m going to write a bit of the theory too, so this might help you even if you’re not using ZF.

The basic idea

As we know, the browser keeps a history of visited pages. However, we can’t access this at all, with the exception of some older version of IE (I think), so we must think of some other way to do it.



The browser usually lets the server see the exact previous page where it came from: the referer URL.
There’s just one problem: it isn’t always populated. Some firewalls can optionally block it, some browsers have an option to turn it off etc., so it can’t be used very reliably.

This is why we need a custom method for tracking urls. Of course, this will only work on our site, but that doesn’t matter – we don’t want to literally spy on our users, now do we?



Since we can see each request the user does to our site, we can employ a simple strategy: Every time the user opens a page, store the opened page’s URL in an array in the session. This way we can collect the browsing history on our page.

The implementation

We could implement this in Zend Framework as a front controller plugin and it would get automatically executed on every request, but it has a limitation. Since it would probaby be nice to be able to access the history, for example to redirect the user back to a page, we can’t go with the front controller plugin.

The best option would probably be a action helper. Just like front controller plugins, they can get automatically executed on every request, but they can also be accessed from the controller actions, making it possible to use the history data easily.



In case you haven’t heard about action helpers, check the action helpers chapter of Zend Framework manual. It will help you understand what the code we’ll be writing soon does.

The code

You can download the code from the Svn. Let’s look at it a bit:

The class should be rather obvious for the most part. Most of the things happen in _initSession and preDispatch, which handle the tracking.

private function _initSession()
{
    $this->_namespace = new Zend_Session_Namespace('CU_Controller_Action_Helper_History');
 
    if(!is_array($this->_namespace->history))
    {
        $this->_namespace->history = array();
 
        if(!empty($_SERVER['HTTP_REFERER']))
            array_unshift($this->_namespace->history, $_SERVER['HTTP_REFERER']);
    }
    else	
        array_splice($this->_namespace->history, $this->_trackAmount);
}

Despite being the biggest method of the class, _initSession is rather simple. It opens a session namespace and sees if there was previous data for the history or not. In case there was nothing in, it also checks the HTTP_REFERER header; this allows us to see at least the refering site where they came from. If there was some data in, it uses array_splice to cut the length of the history to the max limit.

preDispatch simply uses the Url helper to get the current URL and uses array_unshift to make it the 0th index in the array. Rest of the class should be quite obvious.

As can be seen, the history logic works quite simply. Each URL is kept in an array in the session in a namespace so there will be no collisions. The current page is the 0th, the previous is 1st, the one before that 2nd and so on. The default amount of URLs to track is two because that should be enough for the typical scenario of form redirection: You go to a page which links to the form, which you submit, making the initial page the 2nd in history.

Using the class

Using the class is very simple. First, we must add the helper to the HelperBroker, for example in our bootstrap:

Zend_Controller_Action_HelperBroker::addHelper(new CU_Controller_Action_Helper_History());

This is so that the helper gets initialized and will be notified on each request. If we used addPath, the helper would not get initialized before it’s used in a controller, effectively missing preDispatch.

Now, we can use this in our controller:

public function someAction()
{
    $this->_helper->history->goBack(2); //jump back two pages in history
}

We can also use getPreviousUrl or getArray to get the visited URLs without redirecting.

Conclusion

This is a pretty useful feature in my opinion. I often need this kind of things with my forms and so far I’ve actually rewritten the same redirection code again and again.

This could also be expanded from here to track more specific actions, perhaps even how long the user spent between requests. That way it could be used for creating statistics of user behavior on the site, such as navigation paths and other things.

More on PHP:
Three PHP mistakes that will cause you debugging nightmares
Generic collections in PHP
Automating creation and caching of image thumbnails

Share this:
  1. 11 Responses to “Tracking the user’s browsing history with PHP”

  2. STUMBLED!

    This is a fantastic idea and a great piece of code, thanks for sharing.

    By Geoserv on Jan 14, 2009

  3. For use within the site (which you could just do by request) such as which pages the user visited and so on, it’s fine… but as soon as you start looking at their history properly it’s nothing short of an invasion of privacy.

    If the browser sends a referral, I’d consider it acceptable to store this, anonymously, for statistical use. How would you like it, however, if some company stored (alongside your name, address etc) your bank, email, facebook profile and perhaps a quick visit to ann summers… whatever sensitive sites you visit.

    By Jon on Jul 30, 2009

  4. hi, what a nice post..

    this morning i just thinking about such idea…

    then searching “php read user history” through google and ended up here.

    but my purpose little different,
    i just want track my own history, record and display it in my site…

    it will be something like,

    Site i recently visited:
    1. codeutopia.net
    my comment: another great website’
    2. google.com
    my comment: i can’t live without it

    what do you think?

    By takien on Oct 15, 2009

  5. I don’t think you can use PHP to automatically track your own browsing outside your site. If you’re using Firefox, perhaps you should look into writing a plugin? That might be what you need.

    By Jani Hartikainen on Oct 15, 2009

  6. nice one i was looking for this

    By abhishek on Apr 3, 2010

  7. Wow good idea. I used your code as a base, but needed my implementation slightly different. I wanted to remember the get params as well so i slightly altered it. Thnx!

    By Tom Somerville on Mar 29, 2011

  8. I have a question: what happens when a user uses multiple browser windows to navigate your site?
    Wouldn’t the histories of all windows be merged together into one path?

    By Remi on Sep 5, 2011

  9. Remi, yes, that is generally an issue with approaches which use mechanisms like session or cookies.

    By Jani Hartikainen on Sep 5, 2011

  10. Can we use this code with some modification to track user behavior coming to a publisher site so as to show relevant ads to the users? As we call behavioral advertising?

    By David on Dec 9, 2011

  1. 2 Trackback(s)

  2. Jul 15, 2008: Zend History Action Helper(Codeutopia) | Chris Antoine
  3. Jan 14, 2009: Added by a PAL to FAQ PAL

Post a Comment

You can use some HTML (a, em, strong, etc.). If you want to post code, use <pre lang="PHP">code here</pre> (you can replace PHP with the language you are posting)