MSN Live Search API V2.0 in PHP

| | Comments (6)

At the end of 2008, Microsoft abandoned their old search API. While older applications continue to work, new AppID’s only work with the new V2.0 API. If you’ve created a new AppID, and wonder why none of the code samples you find on the Web work with it, now you know. It’s not hard to update code to use the newer (still in beta) V2.0 API, and we’ll do exactly that by updating our previous API search code. If you’ve used the old code, it’s quite simple to update to the new code. Just copy the file, and change one line in your PHP page — the new code requires PHP5, so be sure your server has PHP5 installed.

Quick Update

Get the new Search API V2.0 PHP class and copy it to the same location as the older code. Find the line in your PHP script reading include ("MSNSearch.php") and replace it with include ("MSNSearchV2.php"). You’ll then need to get a new AppID from Microsoft and update your page (V1.0 AppID’s don’t work with V2.0 API, and vice-versa).

How it works

Examine the source code for the class yourself — it formats a HTTP URL and sends it to Microsoft’s server, receiving the search response as XML. It then uses PHP’s SimpleXML to parse the results (only in PHP5, which is why PHP5 is required). The class has a few helper functions to assist so you don’t have to write search forms or format results, and CSS classes tag all HTML code for easy formatting.

Microsoft’s new V2.0 API’s don’t require SOAP (although you can use it if you want), so the previous requirement of a SOAP library disappears. The new V2.0 API’s have the option to send requests as HTTP (returning results formatted as XML) without using SOAP.

To get a functioning search page, place this PHP code snippet in a script and you’ll have a ready-made search page, with a few customizations for your specific site.

  1. Place the Search API V2.0 PHP class in the same directory as your script (or change the include line to point it to the location of where you placed it).
  2. Place your AppID key instead of “INSERTAPIKEYHERE”.
  3. If you don’t have your script on your webserver as /search-msn.php, change the definition of SEARCH_URL.
<?php
define("SEARCH_URL","/search-msn.php");
include("MSNSearchV2.php");

# Values from HTTP GET, or reasonable defaults
$start = isset($_GET['start']) ? intval($_GET['start']) : 1;
$q = isset($_GET['q']) ? $_GET['q'] : "";
if ($start < 1)
    $start = 1;

print searchform($q,"form_top",SEARCH_URL);
if (strlen($q) > 1) {
  $msnsearch = new MSNSearch('INSERTAPIKEYHERE');
  $sresult = false;
  $msnsearch->setQuery($q);
  $msnsearch->setPage($start);
  $sresult = $msnsearch->search();
  if (($sresult === true) && ($msnsearch->totalRecords > 0)) {
    print $msnsearch->search_header($q);
    print $msnsearch->search_results();
    print $msnsearch->search_navagation($q);
    print searchform($q,"form_bottom",SEARCH_URL);
  } else 
    print "<p>Sorry, no results found for <b>$q</b>.</p>\n";
}
?>

All PHP code on this page licensed under a BSD license.

References:

6 Comments

Yes this is a great piece of code but how can i change the source from web to images.

by simply change &sources=web to &sources=image returns a blank screen.??

 

Comparing MS’s documentation for the the Image type verses the Web type reveals some parameters differ. The following would need to be changed as well:

$result .= "&Web.Count=" . $this->recordsPerPage;

$result .= "&Web.Offset=" . ($this->page - 1) * $this->recordsPerPage;

Change “Web” -> “Image”.

Why MS didn’t just call those “Count” and “Offset” is bizarre, but they tied the parameters to the specific query chosen.

Additionally, the Web.Options will likely also cause problems for the Image type, so you might want to try commentating that line out as well — those options may not work for the Image type.

Microsoft’s documentation:

http://msdn.microsoft.com/en-us/library/dd250845.aspx

http://msdn.microsoft.com/en-us/library/dd250862.aspx

 

Do you know if there is a limitation of the query length? I mean, i can send a query with an arbitrary number of chars? I want to restrict the search within a range of websites, that can be quite big, more than 500. I know that is possible to use the site: filter, but i’m not sure if i can send a query with 500 websites inside!

 

Do you know if there is a limitation of the query length?

Reading the MSN API docs, there doesn’t seem to be an expressed limit on URL length, so the best thing is try it and see what happens. If they conform to the HTTP specs, it should work.

Try manually creating your URL and trying it in the browser and see if you get data back, or the 414 error.

From RFC 2616 (HTTP/1.1) Section 3.2.1

The HTTP protocol does not place any a priori limit on the length of a URI. Servers MUST be able to handle the URI of any resource they serve, and SHOULD be able to handle URIs of unbounded length if they provide GET-based forms that could generate such URIs. A server SHOULD return 414 (Request-URI Too Long) status if a URI is longer than the server can handle (see section 10.4.15).

 

thanks for the sample. it is a real help. but when I tried to change the variables from Web to Image, the results don’t show up. it returns nothing, not even number of records.

can you tell me what additional thing I have to do to make it work? I read the MSDN documentation for Image Source Type but the code sample given is in C# and VisualBasic. I am not so much proficient with these languages and hoping to get help in PHP.

 

Microsoft changes many of the names between web and image search, so like comment #2 above, you’ve got to find them all and change them. The Docs are the best guide to find the changes between the two.

If you get no results back, it’s because it errored out somewhere - the API isn’t very friendly with error messages, so it’s trial and error. Look at the example responses and you’ll notice the changes.

http://msdn.microsoft.com/en-us/library/dd250937.aspx (Image parameters) http://msdn.microsoft.com/en-us/library/dd250862.aspx (Image example response) http://msdn.microsoft.com/en-us/library/dd250852.aspx (Web parameters) http://msdn.microsoft.com/en-us/library/dd250894.aspx (Web example response)

In the search() function, start with something like (notice the changes between the web and image versions):

    $xml_results = $xml->children('http://schemas.microsoft.com/LiveSearch/2008/04/XML/multimedia');
    $this->totalRecords = $xml_results->Image->Total;
    $this->totalPages = ceil($this->totalRecords / $this->recordsPerPage);
    if ($this->totalRecords > 0) {
        foreach($xml_results->Image->Results->ImageResult as $item) {
            $this->results[] = array (
                'url' => $item->Url,
                'urlDisplay' => $item->MediaUrl,
                'urlCache' => "",
                'title' => isset($item->Title) && trim($item->Title) != '' ? $item->Title : $item->MediaUrl,
                'width' => isset($item->Width) ? $item->Width : 0,
                'height' => isset($item->Height) ? $item->Height : 0,
                'filesize' => isset($item->FileSize) ? $item->FileSize : 0,
                'thumbnail' => isset($item->Thumbnail->Url) ? $item->Thumbnail->Url : 0,
                'thubmnail-height' => isset($item->Thumbnail->Height) ? $item->Thumbnail->Height : 0,
                'thubmnail-width' => isset($item->Thumbnail->Width) ? $item->Thumbnail->Width : 0,
                'thubmnail-size' => isset($item->Thumbnail->FileSize) ? $item->Thumbnail->FileSize : 0,
                'snippet' => "" //Images don't have snippets
            );
        }
    }

and the getMSNURL() function similar to (as a starting point):

function getMSNURL() {
    $result = "http://api.search.live.net/xml.aspx?";
    $result .= "AppId=" . $this->appID;
    $result .= "&Query=" . urlencode($this->query);
    $result .= "&Sources=Image";
    $result .= "&Version=2.0";
    return $result;
}

All that is UNTESTED, but should give you a starting point to see how it must be done. After that, you’ll have to re-write the search_results() function to handle filesize and the other different results.

I didn’t look up what all the parameters are - some are obvious, but some are similar and could have subtle differences. The MSN API docs should have details.

That should get you started on making the changes. You don’t really need to translate C#->PHP, as what really changed are the input and output parameters. For that, the MSN docs should highlight the changes needed if you dig deep enough.

Have fun!

 

Leave a comment

OpenID Enabled