256 P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s 256 P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s Search Yahoo! Both Yahoo! and Google provide excellent search results, and Microsoft’s Bing search isn’t bad either. But because the quality of Yahoo!’s results is, in my opinion, equal to Google’s, I thought I would root for the underdog and provide a plug-in for Yahoo!’s search API, particularly considering that their API allows unlimited uses per day (although they reserve the right to limit this and/or charge in the future), plus you are permitted to reorder and blend the results with other content. Obviously, with the merger of certain Bing and Yahoo! search assets, the results at Yahoo! seem likely to improve even further, since Microsoft is very keen to catch up on Google’s search engine lead. It also means this plug-in may require updating if the API is changed. So, for the latest details please see http://developer.yahoo.com/search/boss. Anyway, using this plug-in you can provide three arguments to have up to 50 results returned at a time, and can page through the remaining results as deeply as you like. Figure 10-9 shows it being used to find web sites relating to the query yahoo search api. About the Plug-in This plug-in takes a search term and returns results from the Yahoo! search engine. Upon success, it returns a two-element array with the first value being the number of results returned, and the second an array of result details, containing a sub-array in each element, with the following values: • The title • The abstract • The URL to be displayed • The URL for clicking through to FIGURE 10-9 Use this plug-in to add Yahoo! search results to your web site. 76 C h a p t e r 1 0 : A P I s , R S S , a n d X M L 257 C h a p t e r 1 0 : A P I s , R S S , a n d X M L 257 On failure it returns a single-element array with the value FALSE. It requires these arguments: • $search A search string • $start The first result to return • $count The maximum number of results to return Variables, Arrays, and Functions $id String containing a Yahoo! Search API key $url String containing the API URL with $id and $search appended $xml String containing the contents of $url $sxml SimpleXML object created from $xml $data Array containing the results returned $result SimpleXML object extracted from $sxml->resultset_web->result $t String containing the current title $a String containing the current abstract $d String containing the current display URL $c String containing the current click-through URL How It Works Because the search query in $search will be passed to the API as part of a URL, it is first encoded using the rawurlencode() function. Then $search, along with a valid Yahoo! Search API key, in $id, is incorporated with the API URL to create the string $url, which is then passed to the file_get_contents() function to retrieve the results into the variable $xml. The string $id must contain your own unique Yahoo! Search API key; you cannot use the key YahooDemo as you can with some other of the company’s APIs. If you already have such a key, you can locate it by visiting http://developer.yahoo.com/wsregapp/?view and copying the Search API key into your program. If you don’t, you can get one free by visiting http://developer.yahoo.com/wsregapp. Check the box that says Browser Based Authentication, fill in your details, select the Boss Search Service checkbox, and click the Continue button. Once these details have been sent to the API it will return its result in $xml. If it contains the empty string or the value FALSE, then FALSE is returned. An @ symbol is also placed in front of the file_get_contents() call to suppress any error messages. A bit of work then needs to be done to transform the contents of $xml because the function that will be used to process the XML data, simplexml_load_string(), doesn’t seem to like the CDATA that Yahoo! sometimes returns. In XML, a CDATA section is a piece of content that is marked for the parser to interpret as only character data, not markup. So the next few lines of code remove the <![CDATA[ and ]]> tags, leaving behind just the contents. The contents are then made XML-safe by saving all examples of & by converting them to the string [ampersand], and then changing any & symbols that remain into & entities. The [ampersand] strings are then changed back to & entities. After that, all 258 P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s 258 P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s <b>, </b>, and <wbr> tags (the only ones Yahoo! Search seems to employ) are changed into their HTML entity equivalents. At this point, the XML data should be in a format acceptable to SimpleXML, so the contents of $xml are then processed into a SimpleXML object and placed in the object $sxml, and the array that will be used to store all the result details, $data, is also initialized. Now, to retrieve all the results, a foreach loop is used to iterate through $sxml- >resultset_web->result, placing each element into the object $result. From here the title, abstract, display URL, and click-through URL are retrieved into the variables $t, $a, $d, and $c. If $a, the abstract, has a value, then these four variables are grouped into an array and inserted into the next available element of $data. This check is made because sometimes Yahoo! Search results don’t have an abstract, and I choose to ignore such results. Once $data has been populated, a two-element array is returned, with the first element being the number of results returned, and the second an array, each element of which is a sub-array containing the parts of each result. How to Use It As long as you have assigned a valid Yahoo! Search key to $id in the plug-in, you can call it by passing a query string, the number of the first result to return, and the maximum number of results to return, like this: $search = "yahoo search api"; $results = PIPHP_SearchYahoo($search, 1, 10); if (!$results[0]) echo "No matching results found for $search."; In this case, the first result requested is 1, and up to ten results are wanted. If $results[0] is FALSE or has the value 0, then no results were retrieved. Otherwise, the first result is accessible in the following way: $title = $results[1][0][0]; $abstract = $results[1][0][1]; $dispurl = $results[1][0][2]; $clickurl = $results[1][0][3]; And the second result, like this (and so on): $title = $results[1][1][0]; $abstract = $results[1][1][1]; $dispurl = $results[1][1][2]; $clickurl = $results[1][1][3]; The best way to process these results, though, is with a foreach loop, placing each array of results temporarily in a new array such as $result, and then accessing them from there, like this: foreach($results[1] as $result) echo "<a href='$result[3]'>$result[0]<a/><br />". "$result[1]<br />" . "<font color='green'>$result[2]</font><br /><br />"; C h a p t e r 1 0 : A P I s , R S S , a n d X M L 259 C h a p t e r 1 0 : A P I s , R S S , a n d X M L 259 Yahoo! requires that you observe their terms and only ever offer the click-through URL to your users so that their click tracking will be applied. Make sure you don’t use the Display URL in an <a href='…'> tag. If you wish to allow your users to page through the results, you can change the value of the start argument and re-call the plug-in. The Plug-in function PIPHP_SearchYahoo($search, $start, $count) { $search = rawurlencode($search); $id = 'YourAPIKeyMustGoInThisStringOrItMayFail'; $url = 'http://boss.yahooapis.com/ysearch/web/v1/' . "$search?appid=$id&format=xml&start=$start" . "&count=$count"; $xml = @file_get_contents($url); if (!$xml) return array(FALSE); $xml = str_replace('<![CDATA[', '', $xml); $xml = str_replace(']]>', '', $xml); $xml = str_replace('&', '[ampersand]', $xml); $xml = str_replace('&', '&', $xml); $xml = str_replace('[ampersand]', '&', $xml); $xml = str_replace('<b>', '<b>', $xml); $xml = str_replace('</b>', '</b>', $xml); $xml = str_replace('<wbr>', '<wbr>', $xml); $sxml = simplexml_load_string($xml); $data = array(); foreach($sxml->resultset_web->result as $result) { $t = html_entity_decode($result->title); $a = html_entity_decode($result->abstract); $d = html_entity_decode($result->dispurl); $c = $result->clickurl; if (strlen($a)) $data[] = array($t, $a, $d, $c); } return array(count($data), $data); } Get Yahoo! Stock News If you offer any finance-related services, you can add some great content to your site by using this plug-in to retrieve stock information from the Yahoo! Finance web site. With it you can fetch the latest chart for a ticker symbol, along with all the latest news about 7 7 260 P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s 260 P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s that stock. Figure 10-10 shows it being used to display information for Apple Computer, Ticker Symbol: AAPL. About the Plug-in This plug-in takes a stock ticker such as AAPL or MSFT, and returns news and information about the stock. Upon success, it returns a three-element array, the first of which is the number of news items returned; the second is a sub-array of two URLs, the first of which is a small and the second a large intraday chart for the stock; while the third element is a sub- array containing the following report details: • Title • Publishing site • Date • Story summary/description • URL to the original story On failure, a single-element array with the value FALSE is returned. The plug-in requires this argument: • $stock A valid stock ticker symbol such as YHOO or JPM FIGURE 10-10 Add the latest stock news and charts to your web site with this plug-in. . page through the remaining results as deeply as you like. Figure 10-9 shows it being used to find web sites relating to the query yahoo search api. About the Plug- in This plug- in takes a search. return Variables, Arrays, and Functions $id String containing a Yahoo! Search API key $url String containing the API URL with $id and $search appended $xml String containing the contents of $url $sxml SimpleXML. containing the results returned $result SimpleXML object extracted from $sxml->resultset_web->result $t String containing the current title $a String containing the current abstract $d String