PHP Alexa Rank Fetcher Class

The most well known online website popularity measuring stick appears to be Alexa. Alexa provides a wealth of information on a given website, most notably:

  • Popularity rank (the most important one)
  • Reach
  • In-links
  • Speed

Alexa provides this information in many useful formats, including XML. Using the XML provided by Alexa, we can gain access to Alexa information within our pages. I've created a PHP class to make fetching Alexa data free, quick, and easy. The class comes in a PHP4 version and a PHP5 version.

The Code - PHP4 Version

/* the alexa rank class */
class alexa
{
	/* initial vars */
	var $xml;
	var $values;
	var $alexa_address;

	/* the constructor */
	function alexa($alexa_address,$domain)
	{
		$this->alexa_address = $alexa_address;
		$this->xml = $this->get_data($domain);
		$this->set();
	}

	/* gets the xml data from Alexa */
	function get_data($domain)
	{
		$url = $this->alexa_address.'http://'.$domain;
		$xml = file_get_contents($url);
		return $xml;
	}

	/* set values in the XML that we want */
	function set()
	{
		$this->values['rank'] = (preg_match('/POPULARITY URL="[a-z0-9\\-\\.\\/]{1,}" TEXT="([0-9]{1,12})"/',$this->xml,$regs) ? number_format($regs[1]) : 0);
		$this->values['reach'] = (preg_match('/REACH RANK="([0-9]{1,12})"/',$this->xml,$regs) ? number_format($regs[1]) : 0);
		$this->values['linksin'] = (preg_match('/LINKSIN NUM="([0-9]{1,12})"/',$this->xml,$regs) ? number_format($regs[1]) : 0);
	}

	/* returns the requested value */
	function get($value)
	{
		return (isset($this->values[$value]) ? $this->values[$value] : '"'.$value.'" does not exist.');
	}
}

The Code - PHP5 Version

/* the alexa rank class */
class alexa
{
	/* initial vars */
	var $xml;
	var $values;
	var $alexa_address;

	/* the constructor */
	function alexa($alexa_address,$domain)
	{
		$this->alexa_address = $alexa_address;
		$this->xml = $this->get_data($domain);
		$this->set();
	}

	/* gets the xml data from Alexa */
	function get_data($domain)
	{
		$url = $this->alexa_address.'http://'.$domain;
		$xml = simplexml_load_file($url) or die('Cannot retrieve feed');
		return $xml;
	}

	/* set values in the XML that we want */
	function set()
	{
		$this->values['rank'] = ($this->xml->SD->POPULARITY['TEXT'] ? number_format($this->xml->SD->POPULARITY['TEXT']) : 0);
		$this->values['reach'] = ($this->xml->SD->REACH['RANK'] ? number_format($this->xml->SD->REACH['RANK']) : 0);
		$this->values['linksin'] = ($this->xml->SD->LINKSIN['NUM'] ? number_format($this->xml->SD->LINKSIN['NUM']) : 0);
	}

	/* returns the requested value */
	function get($value)
	{
		return (isset($this->values[$value]) ? $this->values[$value] : '"'.$value.'" does not exist.');
	}
}

Using cURL

If you'd rather use the cURL library, you can simply modify the get_data() function:

/* gets the XML data from Alexa */
function get_data($domain)
{
	$url = $this->alexa_address.'http://'.$domain;
	$ch = curl_init();
	$timeout = 5;
	curl_setopt($ch,CURLOPT_URL,$url);
	curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
	curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout);
	$xml = curl_exec($ch);
	curl_close($ch);
	return $xml;
}

The Usage

Provide two paramenters: the path to the XML file (minus the domain) and the domain.

/* retrieve & display rank */
$alexa_connector = new alexa('http://alexa.com/xml/dad?url=','digg.com'); // domain only!
echo 'Rank :: '.$alexa_connector->get('rank'); // returns 118
echo '';
echo 'Reach :: '.$alexa_connector->get('reach'); // returns 95
echo '';
echo 'Links In :: '.$alexa_connector->get('linksin'); // returns 34,414

Do you have any suggestions for this class?


Comments

  1. Gevã

    I did not know Alexia. It’s a good site. Thank’s for the suggest.

    About the class why not put the address site direct in the function get_data? If the address change you only need change in only place. In the constructor you need change in every call of this class.

  2. david

    I waffled between putting it inside the class or giving it to the constructor.

    In the end, I chose the constructor to make the class more “flexible,” so to speak. There are multiple URLs you can retrieve this information from.

  3. osama

    Hello …
    thank you for this script … but the result didn’t contain the alexa rank …

    it looks like :
    Rank :: 0
    Reach :: 745,382
    Links In :: 0

    any explain ….
    thanks anyway for your great effort

  4. david

    Not all sites are given a rank Osama. What should it be?

  5. Parijat Roy

    I am having some kind of error

    firstly in my site i am having php5.0 version, so i tried to use php5.0 (alexia rating) codes given above
    but i get error on this simplexml_load_file function, saying undefined!

    anyways so then i used php4.0 codes, it worked fine, but giving error again at line 31: Warning: preg_match() [function.preg-match]: Unknown modifier ‘]’

    i just copied these codes, what might be the reason?
    Please be a little descriptive, since i have a little knowledge on this object-oriented thing in php.

  6. Parijat Roy

    oh i forgot to say

    the line 31 is this line

    $this->values['rank'] = (preg_match(‘/POPULARITY URL=”([a-z-0-9-./]{1,})” TEXT=”([0-9]{1,12})”/’,$this->xml,$regs) ? number_format($regs[1]) : 0);

    which is having the error

  7. Parijat Roy

    sorry the above line was modified(by me only), but still

    original line 31:

    $this->values['rank'] = (preg_match(‘/POPULARITY URL=”[a-z0-9-./]{1,}” TEXT=”([0-9]{1,12})”/’,$this->xml,$regs) ? number_format($regs[1]) : 0);

    didn’t work :(

  8. david

    Thank you for the heads up Parijat. WordPress mangled my code. I’ve completely replaced the previous PHP4 “set” function above so use that. You’ll notice many more forward slashes.

  9. Parijat Roy

    hi david

    thx for solving that thing. its working fine now and so i can use it with my top-site.

    Thank you

    For others who r using it:

    One small Tip:

    if you need to make the thing dynamic, replace the constructor.

    Replace:

    $alexa_connector = new alexa(‘http://alexa.com/xml/dad?url=','digg.com‘); // domain only!

    with this two line

    $site = $_GET['site'];
    $alexa_connector = new alexa(‘http://alexa.com/xml/dad?url=',$site); // domain only!

    you pass the domain name as get parameter.

    Alternatively, you can use POST method too.

    Hope that helps you.

  10. Kevin

    Hey David,

    How easy would it be to deposit the data into a MySQL database?

    Thanks for a cool tool!

  11. david

    @Kevin: Extremely easy — you’d just add the MySQL code to my code above.

  12. neekey

    Yeah.but how can I parse the tag and get the text?

  13. david

    @neekey: It’s all above…

  14. neekey

    I mean I want to get more tags like ADDR,LANG,SPEED, and so on.
    could you do it?Thank you very much.
    It is really a useful lib :)

  15. Dale

    Absolutely brilliant! Thank you for this class – it’s a real help. :-)

  16. Dave

    Thank you for the brilliant class you’ve made. I just want to suggest if you can make it by URL/page not by domain only. Thank you :-)

  17. eytan chen

    It seems as though Alexa have changed their method and no longer provide this data for free, but rather by payment through Amazon servers. Is that correct??

  18. Kevin

    Eytan, you might be right: http://aws.amazon.com/awis/

    Question is, how is my Firefox SearchStatus Addon still working?

  19. jason

    Is CURL a better option? What are the pros/cons? Do you have an opinion?

  20. slym

    This is a great post, fortunately 70% of the time of website owner is consumed in experimenting towards increasing page rank and alexa rank. To start with increasing page rank one must start with downloading Alexa toolbar for IE or firefox on as many system possible. as a second step alexa widget on every page of your website, by this way every webpage opened is counted while calculating rank inspite is user does not have alexa toolbar installed knowtheworldaround.com

  21. SEOLink Resources

    The code below cannot fetch the data from alexa –
    $alexa_connector = new alexa(‘http://alexa.com/xml/dad?url=

    I used PHP5 version and replaced the above code with it. Will try to modify the code and use it on http://seoadsense.free2step.com/index.php/seo-tools/page-rank-checker/ and see how it goes.

  22. Ahmad

    it’s not working anymore :(

    anyone got a new code for it ?

  23. Marvel Comic

    Do you know information about names of field in XML data that Alexa send? Here it is a part of XML data

  24. Marvel Comic

    Oops.. It looks like your comment engine cut XML data.. Try again

    <ALEXA VER=”0.9″ URL=”google.com/” HOME=”0″ AID=”=”>
    <RLS PREFIX=”http://” more=”255″>
    <RL HREF=”www.zoneedit.com/” TITLE=”ZoneEdit”/>
    <RL HREF=”www.tzo.com/” TITLE=”Tzo.com The Reliable Dynamic Dns Service”/>
    </RLS>
    <SD TITLE=”A” FLAGS=”DMOZ”>

  25. Wonderful Directory

    i think the script its not working anymore, because alexa.com use pay subscription for this kind of service

  26. victor

    Script not working
    return Warning: file_get_contents(): HTTP request failed! HTTP/1.0 404 Not Found

  27. Gardinen Stores

    ok, if they want $$$ for xml… we can just download the whole page containing the information ;).. but there must be some other way, because there are free toolbars which showing the alexa numbers without parsingthe whole page…

  28. Plr Ebooks

    I tried this code and its working rather sweetly


    function Alexa($domain) {
    $remote_url = 'http://data.alexa.com/data?cli=10&dat=snbamz&url='.trim($domain);
    $search_for = '', $str[1]));
    $str = explode('TEXT="', $str);
    return number_format($str[1]);
    }
    echo "Alexa ranking: " . Alexa("http://www.google.com");

  29. Andrea

    Hi,

    I have made a slightly different version.
    I am interested in evaluating a list of sites printing for each site the Alexa rank popularity.

    <?php
    function AlexaRank( $url )
    {

    preg_match( '##si’, file_get_contents(‘http://data.alexa.com/data?cli=10&dat=s&url=‘ . $url), $p );
    return ( $p[2] ) ? number_format( intval($p[2]) ):0;
    }

    ?>

    <?php
    $file= file_get_contents("http:///www.yoursite.com/sitelist.txt&quot;);

    // Place each line of $userfile into array
    $domains = explode("\n",$file);

    foreach ( $domains as $domain )
    {

    echo $domain, ' – Rank', AlexaRank( $domain ), ' – ' , "“. “whois“, ‘ – ‘,PHP_EOL;

    }
    ?>

  30. snowsh

    hmmm….

    i can see all the XML:


    I noticed some errors in the function set() so removed the number format operator.
    It returns the back links, but not the RANK or REACH value, which is present in the actual XML…

    my updated class and call:

    //
    /* the alexa rank class */
    class alexa
    {
    /* initial vars */
    var $xml;
    var $values;
    var $alexa_address;

    /* the constructor */
    function alexa($alexa_address,$domain)
    {
    $this->alexa_address = $alexa_address;
    $this->xml = $this->get_data($domain);
    $this->set();
    }

    /* gets the xml data from Alexa */
    function get_data($domain)
    {
    $url = $this->alexa_address.'http://'.$domain;
    $xml = simplexml_load_file($url) or die('Cannot retrieve feed');
    return $xml;
    }

    /* set values in the XML that we want */
    function set()
    {
    $this->values['rank'] = ($this->xml->SD->POPULARITY['TEXT'] ? ($this->xml->SD->POPULARITY['TEXT']) : 0);

    $this->values['owner'] = ($this->xml->SD->OWNER['NAME'] ? ($this->xml->SD->OWNER['NAME']) : 0);
    $this->values['email'] = ($this->xml->SD->EMAIL['ADDR'] ? ($this->xml->SD->EMAIL['ADDR']) : 0);
    $this->values['reach'] = ($this->xml->SD->REACH['RANK'] ? ($this->xml->SD->REACH['RANK']) : 0);
    $this->values['linksin'] = ($this->xml->SD->LINKSIN['NUM'] ? ($this->xml->SD->LINKSIN['NUM']) : 0);
    }

    /* returns the requested value */
    function get($value)
    {
    return (isset($this->values[$value]) ? $this->values[$value] : '"'.$value.'" does not exist.');
    }
    }
    echo "";
    echo "Alexa rank details: ";

    /* retrieve & display rank */
    $alexa_connector = new alexa('http://data.alexa.com/data?cli=10&dat=snbamz&url=','google.com'); // domain only!
    echo 'Rank :: '.$alexa_connector->get('rank').""; // returns 118
    echo $alexa_connector->get('owner');
    echo 'Reach :: '.$alexa_connector->get('reach').""; // returns 95
    echo $alexa_connector->get('email');
    echo 'Links In :: '.$alexa_connector->get('linksin').""; // returns 34,414
    echo "";
    //

    Any ideas?

  31. snowsh

    hmm that didnt work to well!

  32. snowsh

    so this is the xml output: i hope! if not you can see it at

    http://data.alexa.com/data?cli=10&dat=snbamz&url=snowsh.com

  33. snowsh

  34. Keshabraj

    Hi, I have a question.
    suppose I am displaying xml alexa rank in my webpage, how do I display list of “websites” similar to my alexa rank.

    anticipate for your response.

    thank you..

  35. Keshabraj

    similar mean
    +1,+2 or -1 , -2 ranking website list.

    like my site alexa rank is 4445
    similar site for my site is
    aaa.com – 4442
    bbb.com – 4443
    aac.com – 4444
    aab.com – 4446
    aax.com – 4447
    aad.com – 4448

  36. Graham McLellan

    Here’s my class in action: http://www.swordfoxdesign.co.nz/resources/alexa-rank-tool/


    class alexa
    {
    /* initial vars */
    var $alexa_address='http://data.alexa.com/data?cli=10&dat=s&url=';

    function wp_xml2array($__url){
    $xml_values = array();
    $contents = file_get_contents($__url);
    $parser = xml_parser_create('');
    if(!$parser)
    return false;

    xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, 'UTF-8');
    xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
    xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
    xml_parse_into_struct($parser, trim($contents), $xml_values);
    xml_parser_free($parser);
    if (!$xml_values)
    return array();

    $xml_array = array();
    $last_tag_ar =& $xml_array;
    $parents = array();
    $last_counter_in_tag = array(1=>0);
    foreach ($xml_values as $data)
    {
    switch($data['type'])
    {
    case 'open':
    $last_counter_in_tag[$data['level']+1] = 0;
    $new_tag = array('name' => $data['tag']);
    if(isset($data['attributes']))
    $new_tag['attributes'] = $data['attributes'];
    if(isset($data['value']) && trim($data['value']))
    $new_tag['value'] = trim($data['value']);
    $last_tag_ar[$last_counter_in_tag[$data['level']]] = $new_tag;
    $parents[$data['level']] =& $last_tag_ar;
    $last_tag_ar =& $last_tag_ar[$last_counter_in_tag[$data['level']]++];
    break;
    case 'complete':
    $new_tag = array('name' => $data['tag']);
    if(isset($data['attributes']))
    $new_tag['attributes'] = $data['attributes'];
    if(isset($data['value']) && trim($data['value']))
    $new_tag['value'] = trim($data['value']);

    $last_count = count($last_tag_ar)-1;
    $last_tag_ar[$last_counter_in_tag[$data['level']]++] = $new_tag;
    break;
    case 'close':
    $last_tag_ar =& $parents[$data['level']];
    break;
    default:
    break;
    };
    }
    return $xml_array;
    }

    //
    // use this to get node of tree by path with '/' terminator
    //
    function wp_get_value_by_path($__xml_tree, $__tag_path)
    {
    $tmp_arr =& $__xml_tree;
    $tag_path = explode('/', $__tag_path);
    foreach($tag_path as $tag_name)
    {
    $res = false;
    foreach($tmp_arr as $key => $node)
    {
    if(is_int($key) && $node['name'] == $tag_name)
    {
    $tmp_arr = $node;
    $res = true;
    break;
    }
    }
    if(!$res)
    return false;
    }
    return $tmp_arr;
    }

    function getRank($url)
    {
    $arr = $this->wp_xml2array($this->alexa_address.$url);
    $arr2= $this->wp_get_value_by_path($arr, 'ALEXA');

    $arr3=($arr2[2][0]['attributes']);
    $rank=$arr3['TEXT'];

    $rank=($rank=='' ? 'Not ranked yet' : $rank);

    return $rank;
    }
    }

    Call using this:


    $alexa = new Alexa();

    $rank = $alexa->getRank(str_replace('http://', '', $url));

  37. Roman

    Sorry, i didnt added code tag… lawl..


    function AlexaRank( $url )
    {
    preg_match( '##si', file_get_contents('http://data.alexa.com/data?cli=10&dat=s&url=' . $url), $p );
    return ( $p[2] ) ? number_format( intval($p[2]) ):0;
    }

    Here

    http://www.igloro.info/en/pagerank.html

  38. Ashok sharma

    Great post.
    Exactly what I was looking for my website


Be Heard!

Share your thoughts without being a jerk! And wrap your code in <code> tags, f00!

Name*:
Email*:
Website: