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:








Quodlibet [Visitor] wrote:
Very nice.
Link
lagroue [Visitor] wrote:
Great, I was wondering how to get through MSN api.
Many thanks !
Link
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?
Link
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.
Link
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
Link
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
Link
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?
Link
Daniel [Visitor] wrote:
Replacing Ã… with “Å” wasen’t displayed correct before…
Link
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.
Link
Anthony [Visitor] wrote:
I’m sorry.
I could copy php-scripts.
Anthony,
Link
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
Link
Automated Blog [Visitor] wrote:
Thanks for the share of the resource!
http://www.blogtorank.com/
Link
Automated Blog [Visitor] wrote:
What if it searches, displays results amount but doesn’t show the actual content?
What can be causing that issue?
Link
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 ?
Link
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?
Link
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/
Link
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’);
Link