Dopo aver introdotto il lettore all'utilizzo del servizio di ricerca Yahoo BOSS, è giunto il momento di approfondire l'argomento con qualche esempio più dettagliato che ci suggerisca alcuni possibili casi d'uso in una situazione reale.
Gli ingredienti di questi paragrafi saranno i concetti già presentati riguardanti il funzionamento del servizio, in modo particolare dell'interfaccia di tipo REST, con l'aggiunta di alcune indicazioni riguardanti l'uso dell'estensione SimpleXML per l'interpretazione dei risultati. Tale estensione è già attiva di default nelle normali installazioni di PHP5.
Interpretare la risposta XML
Per semplicità, nella nostra ricerca riutilizzeremo il codice già proposto e spiegato in precedenza, che andremo ad elaborare a seconda delle nostre esigenze:
// Application ID
// Alcuni parametri
$param[] = "appid={$appid}";
$param[] = "format=xml"; // Risposta in XML
$param[] = "filter=-porn"; // Filtro pornografia
$param[] = "type=html"; // Solo documenti html nei risultati
// Costruisco la stringa dei parametri tipo param1=value¶m2=value2&...
// Pulizia query
die("Cosa stai cercando?");
}
$query = urlencode($_REQUEST['query']);
// URL del servizio
// Effettuo la chiamata HTTP ed ottengo la risposta XML
// Gestione dei risultati
// ...
La richiesta HTTP al servizio di ricerca viene effettuata mediante la funzione file_get_contents(), ma potrebbe essere eseguita in modo analogo tramite la funzione curl_get_contents()
proposta in precedenza. Nel codice di esempio, la variabile $result
è una stringa che viene popolata con il documento XML di risposta. Per trasformare questa stringa in una struttura dati facilmente gestibile, è sufficiente utilizzare la funzione simplexml_load_string() che genera un oggetto (di tipo SimpleXMLElement) con alcune particolarità molto semplici. Il seguente codice crea appunto tale oggetto nella variabile $xml:
$xml = simplexml_load_string($result);
La struttura del documento XML di risposta era già stata presentata in precedenza. In modo particolare, abbiamo notato che all'interno del nodo radice, è presente un nodo figlio che contiene l'intero insieme dei risultati, in inglese result set, chiamato appunto <resultset_web>
. Nel nostro oggetto $xml
, l'accesso a questo elemento avviene semplicemente come se si trattasse di una variabile pubblica, ossia $xml->resultset_web
(a sua volta un oggetto). Nel documento XML, osserviamo che il tag possiede alcuni attributi, che possiamo recuperare sfruttando le funzionalità di SimpleXML:
foreach ($xml->resultset_web->attributes() as $key => $value) {
echo "Attributo {$key}: valore {$value}<br />";
}
La funzione SimpleXMLElement::attributes() restituisce quindi gli attributi dell'elemento XML in questione sotto forma di array associativo. Nel nostro caso ci aspettiamo di ottenere i valori per i seguenti attributi:
- count
- start
- deephits
- totalhits
Un altro modo per estrarre questi attributi può essere il seguente:
foreach ($xml->resultset_web->attributes() as $key => $value) {
$$key = $value;
}
In tal modo, potremo disporre in seguito delle variabili $start
, $count
, $deephits
e $totalhits
: attenzione comunque a non causare un conflitto con nomi di altre variabili precedentemente dichiarate.
All'interno del tag <resultset_web>
troveremo vari nodi <result>
che rappresentano ciascuno dei risultati recuperati. In $xml->resultset_web
sarà quindi presente una variabile result di tipo array che conterrà tutti i nostri risultati, sempre sotto forma di semplici oggetti:
foreach ($xml->resultset_web->result as $res) {
// $res è il singolo risultato
L'oggetto $res
conterrà a sua volta ulteriori variabili pubbliche, andando a rappresentare i vari nodi ottenuti nella risposta XML e descritti in precedenza. Proponiamo quindi di seguito una modifica alla parte di codice che si preoccupa della gestione dei risultati, con il fine di stamparli a video in modo simile a quanto avviene nei più comuni motori di ricerca:
if ($result = file_get_contents($url)) {
// Gestione dei risultati
foreach ($xml->resultset_web->attributes() as $k => $v) {
$$k = $v; // estraggo gli attributi di <resultset_web>
}
$res_start = $start + 1;
$res_end = $start + $count;
echo "<p>Risultati: {$res_start}-{$res_end} di {$deephits} per la ricerca su <b>{$_REQUEST['query']}</b></p>";
foreach ($xml->resultset_web->result as $res) {
echo '<p><a href="' . $res->clickurl . '">' . $res->title . '</a><br />';
if (!empty($res->abstract)) {
echo $res->abstract.'<br />';
}
echo '<span style="color: darkgreen;">' . $res->url . '</span></p>';
}
}
Nel dettaglio, gli attributi dell'oggetto $res che ci possono essere utili sono i seguenti:
- title
- abstract
- url
- size
- clickurl
Ricordiamo che se vogliamo, come in quest'ultimo esempio, creare un link ai risultati mediante il tag <a>
, da Yahoo ci viene richiesto di utilizzare il campo clickurl dei risultati, e non direttamente url: questo per consentire un monitoraggio sull'uso del servizio. Notiamo inoltre che negli attributi abstract
e title
, le parole chiave cercate vengono evidenziate in grassetto mediante il relativo tag <b>
.
Ricerca in una specifica lingua
Tra i parametri che possiamo definire in fase di ricerca, abbiamo anche la possibilità di restringere i risultati ad una specifica lingua o regione. A questo proposito, è sufficiente aggiungere tra i parametri di ricerca i termini lang region
Il modulo di ricerca potrebbe essere quindi modificato come segue:
<form action="boss_example.php">
Cerca risultati
<select name="lang">
<option value="">in tutte le lingue</option>
<option value="it">solo in italiano</option>
<option value="de">solo in tedesco</option>
</select><br />
<input type="text" name="query" />
<input type="submit" name="submit" value="Cerca" />
</form>
Per il codice PHP dedicato alla ricerca, invece, la modifica consiste nel modificare l'array $param aggiungendo i parametri indicati, se necessario:
// Alcuni parametri
$param[] = "appid={$appid}";
$param[] = "format=xml"; // Risposta in XML
$param[] = "filter=-porn"; // Filtro pornografia
$param[] = "type=html"; // Solo documenti html nei risultati
if (!empty($_REQUEST['lang'])) {
$param[] = "lang={$_REQUEST['lang']}";
$param[] = "region={$_REQUEST['lang']}";
}
La lista completa delle sigle a due lettere di tutte le lingue e tutti i paesi disponibili è indicata sulla documentazione ufficiale di Yahoo BOSS.
Restringere la ricerca ad un singolo sito
Un'ulteriore funzionalità che possiamo offrire ai nostri utenti consiste nel restringere la ricerca ad uno specifico dominio (probabilmente il nostro). Praticamente tutti i motori di ricerca consentono di effettuare questa operazione aggiungendo la parola chiave site:miodominio.xx
<form action="boss_web_search.php" method="post">
Cerca risultati
<select name="site">
<option value="">su tutto il web</option>
<option value="html.it">su HTML.it</option>
</select>
<input type="text" name="query" />
<input type="submit" name="submit" value="Cerca" />
</form>
in modo analogo a quanto già indicato per la lingua, dal punto di vista del codice PHP che effettua la ricerca è sufficiente aggiungere un elemento all'array $param che stiamo utilizzando:
if ($_REQUEST['site'] == 'html.it') {
$param[] = "sites=html.it";
}
In questo esempio abbiamo ristretto la ricerca al singolo dominio html.it, ma volendo è possibile utilizzare il parametro sites specificando una lista di domini in cui cercare, separati da virgole.
Ulteriori spunti
A questo punto sarà la nostra fantasia a trovare il modo migliore per integrare il servizio di ricerca di Yahoo nel nostro sito web. Una possibile evoluzione del nostro codice potrebbe essere l'aggiunta della funzionalità di paginazione, per scorrere i risultati oltre i primi 10. Per fare ciò, è necessario impostare in modo appropriato i parametri count
start
count
count
start
Per semplificare la questione, nel documento XML ottenuto in risposta abbiamo anche un nodo <nextpage>
$xml->nextpage
http://boss.yahooapis.com
I prossimi esempi, argomento del prossimo articolo, riguarderanno la ricerca all'interno degli archivi delle immagini e delle news.