Sep152005

MSN Search API PHP Client

Microsoft has recently published their own MSN Search API (now competing with Google and Yahoo) implemented as a SOAP Web Service. After some deliberation on the MSN Search API forums, I managed to develop a small PHP class to handle the API (thanks to quodlibet for his help identifying a small bug.)

The class uses nuSOAP for interacting with the SOAP server. You will need to download nuSOAP and copy it inside a folter named nusoap, located in the same location as this class’ file.

The source code for the class is the following (save it as MSNWebSearch.class.php):

<?php

define ('NUSOAP_PATH', dirname(__FILE__) . '/nusoap');
define ('MSN_API_KEY', 'Insert here your default MSN API key');
define ('MSN_API_ENDPOINT', 'http://soap.search.msn.com/webservices.asmx');
define ('MSN_API_NAMESPACE', 'http://schemas.microsoft.com/MSNSearch/2005/09/fex');

require_once(NUSOAP_PATH . '/nusoap.php');

class MSNWebSearch
{
	var $apiKey;
	var $filterAdult;
	var $languages;
	var $page;
	var $pages;
	var $query;
	var $records;
	var $recordsPerPage;

	function &MSNWebSearch($apiKey = null)
	{
		$this->apiKey = isset($apiKey) ? $apiKey : MSN_API_KEY;
		$this->filterAdult = false;
		$this->languages = 'en-US';
		$this->recordsPerPage = 10;
		$this->page = 1;
	}

	function getApiKey()
	{
		return $this->apiKey;
	}

	function setApiKey($apiKey)
	{
		$this->apiKey = $apiKey;
	}

	function getErrorMessage()
	{
		return $this->errorMessage;
	}

	function getFilterAdult()
	{
		return $this->filterAdult;
	}

	function setFilterAdult($filterAdult)
	{
		$this->filterAdult = $filterAdult;
	}

	function getLanguages()
	{
		return $this->languages;
	}

	function setLanguages($languages)
	{
		$this->languages = $languages;
	}

	function getPage()
	{
		return $this->page;
	}

	function setPage($page)
	{
		if ($page < 1)
		{
			$page = 1;
		}

		$this->page = $page;
	}

	function getPages()
	{
		return $this->pages;
	}

	function getQuery()
	{
		return $this->query;
	}

	function setQuery($query)
	{
		$this->query = $query;
	}

	function getRecords()
	{
		return $this->records;
	}

	function getRecordsPerPage()
	{
		return $this->recordsPerPage;
	}

	function setRecordsPerPage($recordsPerPage)
	{
		$this->recordsPerPage = is_int($recordsPerPage) && $recordsPerPage > 0 ? $recordsPerPage : 10;
	}

	function get()
	{
		$startIndex = ($this->page - 1) * $this->recordsPerPage;
		$elementsCount = $this->recordsPerPage;

		$parameters = array(
			'AppID' => $this->apiKey,
			'Query' => $this->query,
			'CultureInfo' => $this->languages,
			'SafeSearch' => ($this->filterAdult ? 'Strict' : 'Off'),
			'Requests' => array (
				'SourceRequest' => array (
					'Source' => 'Web',
					'Offset' => $startIndex,
					'Count' => $elementsCount,
					'ResultFields' => 'All'
				)
			)
		);

		if (isset($this->country))
		{
			$parameters['Location'] = $this->country;
		}

		$soapClient =& new soapclient(MSN_API_ENDPOINT);

		$soapResult = $soapClient->call('Search', array ('Request' => $parameters), MSN_API_NAMESPACE );

		if ($soapClient->getError())
		{
			$this->errorMessage = $soapClient->getError();

			return false;
		}

		$this->records = $soapResult['Responses']['SourceResponse']['Total'];
		$this->pages = ceil($this->records / $this->recordsPerPage);

		if (is_array($soapResult['Responses']['SourceResponse']['Results']))
		{
			$result = array();

			foreach ($soapResult['Responses']['SourceResponse']['Results'] as $item)
			{
				$result[] = array (
					'url' => $item['Url'],
					'urlDisplay' => $item['DisplayUrl'],
					'urlCache' => $item['CacheUrl'],
					'title' => isset($item['Title']) && trim($item['Title']) != '' ? $item['Title'] : $item['DisplayUrl'],
					'snippet' => $item['Description']
				);
			}
		}
		else
		{
			$result = array();
		}

		return $result;
	}
}
?>

The usage of this class is quite simple. Take a look at the following index.php file to see an example. You can see it working here. Please note that where it says 'My MSN API Key', you need to insert your own MSN API Key. If you don’t have one, get one now.

<?php
require_once(dirname(__FILE__) . '/MSNWebSearch.class.php');

if (isset($_GET) && isset($_GET['query']) && trim($_GET['query']) != '')
{
	$currentPage = 1;

	if (isset($_GET['page']))
	{
		$currentPage = $_GET['page'];
	}

	$msnSearch =& new MSNWebSearch();

	$msnSearch->setApiKey('My MSN API Key');
	$msnSearch->setQuery($_GET['query']);
	$msnSearch->setPage($currentPage);

	$result =& $msnSearch->get();

	if ($result !== false)
	{
		if ($msnSearch->getPages() > 1)
		{
			$navigation = array();

			$navigation['pages'] = $msnSearch->getPages();

			if ($msnSearch->getPage() > 1)
			{
				$navigation['back'] = $PHP_SELF . '?page=' . ($msnSearch->getPage() - 1) . '&query=' . urlencode($msnSearch->getQuery());
			}

			if ($msnSearch->getPage() < $msnSearch->getPages())
			{
				$navigation['next'] = $PHP_SELF . '?page=' . ($msnSearch->getPage() + 1) . '&query=' . urlencode($msnSearch->getQuery());
			}
		}
	}
}
?>
<html>
	<head>
		<titlevMSN Web Search</title>
	</head>
	<body>
		<center><p>
			<form action="<?php echo $PHP_SELF; ?>" method="GET">
				Search:
				<input type="text" name="query" size="70" value="<?php echo isset($_GET['query']) ? $_GET['query'] : ''; ?>" />
				<input type="submit" value="Search" />
				<?php
				if (isset($msnSearch) && $result !== false)
				{
				?>
				<br />
				<b><?php echo $msnSearch->getRecords(); ?></b> records matched your query.
				<?php
				}
				?>
			</form>
		</p></center>
		<?php
		if (isset($msnSearch) && $result === false)
		{
			?>
			There was an error with your search. Error message: <b><?php echo $msnSearch->getErrorMessage(); ?></b>.
			<?php
		}
		else if (isset($msnSearch))
		{
			if (isset($navigation))
			{
			?>
			<center><p>
				Pages: <b><?php echo $msnSearch->getPages(); ?></b>
				<?php
				if (isset($navigation['back']))
				{
				?>
				<a href="<?php echo $navigation['back']; ?>">Previous</a>
				<?php
				}

				if (isset($navigation['back']) && isset($navigation['next']))
				{
				?>
				|
				<?php
				}

				if (isset($navigation['next']))
				{
				?>
				<a href="<?php echo $navigation['next']; ?>">Next</a>
				<?php
				}
				?>
			</p></center>
			<?php
			}
			?>
			<ul>
			<?php
			foreach ($result as $item)
			{
			?>
			<li>
				<a href="<?php echo $item['url']; ?>"><?php echo $item['title']; ?></a>: <?php echo $item['snippet']; ?>
				<br />
				<font color="#008000"><?php echo $item['urlDisplay']; ?></font> - <a href="<?php echo $item['urlCache']; ?>">Cache</a>
			</li>
			<?php
			}
			?>
			</ul>
			<?php
		}
		?>
	</body>
</html>

Hope this helps anyone.

UPDATE [Aug 20, 2006]: After receiving some emails saying that the class didn’t work (which in fact does), I decided to publish a ZIP file that contains a working MSN Search Based Page. It includes nuSOAP as of July 19, 2006. First, download the ZIP file. Then, uncompress to a new directory on your webserver and EDIT the file index.php, looking for line 3. Insert your MSN API KEY there. After specifying your API key, you should be good to go for testing.

Related posts:

  1. Get a taste of AJAX with PHP


Leave a Comment

17 Comments to "MSN Search API PHP Client"

  1. Sep162005 at 3:45 am

    Quodlibet [Visitor] wrote:

    Very nice.

  2. Sep172005 at 11:31 am

    lagroue [Visitor] wrote:

    Great, I was wondering how to get through MSN api.
    Many thanks !

  3. Sep232005 at 8:10 pm

    Noah [Visitor] wrote:

    This is a stupid question, but… has anything changed? I’m gettng soapenv:Client: Client Error

    Pretty sure I placed my MSN API in the right place, but is there any way to get more verbose debug info?

  4. Sep292005 at 2:09 am

    Paul Saffery [Visitor] wrote:

    On lines 149 and 152 of your class you refer to:

    $soapResult['Responses']['SourceResponse']['Results']

    As index.php was not working I used var_dump to find out what was going on and I reckon you should instead refer to:

    $soapResult['Responses']['SourceResponse']['Results']['Result']

    Felicitaciones Mariano!
    Nice piece of work,
    Paul.

  5. Oct122005 at 8:57 am

    Xen [Visitor] wrote:

    Using this:

    I’m posting this

    App ID
    Budhism
    en-US
    Strict

    Web
    0
    10
    All

    but geeting error

    can anyone help…
    Thanks

  6. Oct122005 at 8:59 am

    Xen [Visitor] wrote:

    Using this:

    <form method="post" enctype="multipart/form-data" action="http://soap.search.msn.com/webservices.asmx">

    <input type="file" name="F1">

    <input type="submit" value="Submit" name="B1">

    </form>

    I’m posting this

    <?xml version="1.0" encoding="ISO-8859-1"?>

    <SOAP-ENV:Envelope

    SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"

    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">

    <SOAP-ENV:Body><ns3849:Search xmlns:ns3849="http://tempuri.org">

    <Request>

    <AppID xsi:type="xsd:string">App ID</AppID>

    <Query xsi:type="xsd:string">Budhism</Query>

    <CultureInfo xsi:type="xsd:string">en-US</CultureInfo>

    <SafeSearch xsi:type="xsd:string">Strict</SafeSearch>

    <Flags xsi:type="xsd:string"></Flags>

    <Location xsi:type="xsd:string"></Location>

    <Requests><SourceRequest><Source xsi:type="xsd:string">Web</Source>

    <Offset xsi:type="xsd:int">0</Offset>

    <Count xsi:type="xsd:int">10</Count>

    <ResultFields xsi:type="xsd:string">All</ResultFields>

    </SourceRequest></Requests></Request></ns3849:Search></SOAP-ENV:Body>

    </SOAP-ENV:Envelope>

    but geeting error

    can anyone help…

    Thanks

     

  7. Jan142006 at 11:08 am

    Daniel [Visitor] wrote:

    I have a problem with special characters like Æ Ø Ã… where used in the searchstring doesn’t display the proper result from MSN.

    I have tried to do a string rewrite replacing the character with it’s entity name ie replacing Ã… with Å but still no luck

    If I then replace Ã… with Aa (same meaning in Danish) I do get some ok results but not the same as if I used Ã…

    So what to do?

  8. Jan142006 at 11:10 am

    Daniel [Visitor] wrote:

    Replacing Ã… with “Å” wasen’t displayed correct before…

  9. Apr262006 at 2:08 am

    Anthony [Visitor] wrote:

    Hi,
    I’m Anthony.
    I’m interesting in this page’s php-script.
    But I can’t copy those script,because it’s image file.
    I would like to download it.
    if there is text of scritp,please tell me link url.
    Thanking you in advance.

  10. Apr262006 at 3:07 am

    Anthony [Visitor] wrote:

    I’m sorry.
    I could copy php-scripts.
    Anthony,

  11. May102006 at 1:48 am

    AL [Visitor] wrote:

    i use the script and it says and error that it couldn’t open socket connection to server at msn

    please tell me how to fix this
    e-mail me if you have time

  12. May302006 at 2:48 pm

    Automated Blog [Visitor] wrote:

    Thanks for the share of the resource!

    http://www.blogtorank.com/

  13. May302006 at 3:25 pm

    Automated Blog [Visitor] wrote:

    What if it searches, displays results amount but doesn’t show the actual content?

    What can be causing that issue?

  14. Jul192006 at 7:05 pm

    Matthuffy [Visitor] wrote:

    Why do the results now show. It clearly says that it has found X amount, but all it shows is the “- Cache”. No tital and no discription?

    Any ideas why this is ?

  15. Aug182006 at 6:46 pm

    Maurice [Visitor] wrote:

    I put the script on my server but when I search for something he show me the number of results en pages. And NO search results, only the link to Cache.

    What have I done wrong? How can I get this working?

  16. Oct222006 at 11:49 am

    Dennis [Visitor] wrote:

    This error keeps on popping out on mine….
    soapenv:Client: Client Error

    You can find the script installed here
    http://www.joomlabs.com/msn/

  17. Jan292010 at 8:42 am

    vijesh wrote:

    define (‘MSN_API_NAMESPACE’, ‘http://schemas.microsoft.com/MSNSearch/2005/09/fex‘);

    getting the error message

    Fatal error: Uncaught SoapFault exception: [Client] Function (“call”) is not a valid method for this service in E:\xampp\htdocs\gopit\MSNWebSearch.class.php:137 Stack trace: #0 [internal function]: SoapClient->__call(‘call’, Array) #1 E:\xampp\htdocs\gopit\MSNWebSearch.class.php(137): SoapClient->call(‘Search’, Array, ‘http://schemas….‘) #2 E:\xampp\htdocs\gopit\index.php(530): MSNWebSearch->get() #3 {main} thrown in E:\xampp\htdocs\gopit\MSNWebSearch.class.php on line 137

    I think it is due to the API namescape
    it is not working
    please chk and update the

    define (‘MSN_API_NAMESPACE’, ‘http://schemas.microsoft.com/MSNSearch/2005/09/fex‘);

 
Powered by Wordpress and MySQL. Clauz's design for by Cricava