Pull to refresh

Поисковое API для PHP (Flash, Java и других)

Reading time 5 min
Views 6.6K
Задача: организовать поиск по всему сайту затратив как можно меньше усилий и оформить результаты в своем стиле.

Рассуждение
Есть различные серверные системы для организации полнотекстового поиска индексируя сайт, индексирую базу данных. Но их надо устанавливать на своем сервере, настраивать, а некоторые из них еще и платные.
В какой-то момент решил воспользоваться Google Ajax Search API через JavaScript, но тут вид результатов менять достаточно сложно, да и еще надо делать запросы в другой домен при помощи javascript.

Решение
В итоге набрел на странице Google AJAX Search API в раздел Code Snippets и все стало просто: немного кода на php и полнотекстовый поиск по любому сайту готов.


PHP


Приведен слегка упрощенный фрагмент кода. Конечно, хорошо бы сделать проверку на доступность сервера ajax.googleapis.com в данный момент.

<?php
//Получаем настройки поискового запроса
$data    = MyDB::get() -> selectOne('*',self::TABLE,'`id_mod` = '.$this->id_mod);

//На каком сайте ищем?
$sireUrl = $data['url'];

//Данные полученные от пользователя
$sigs = array(
  'q'    => array('type' => 'string', 'required' => false),
  'start'  => array('type' => 'integer', 'required' => false)
);
$reqData = SpeData::sanitize_vars($this->queryArray, $sigs, 'RequestException');    
$q     = urlencode($reqData['q'].' site:'.$sireUrl);
$start   = empty($reqData['start']) ? 0 : $reqData['start'];

//Отправляем запрос гуглу, собственно это основаня часть :)
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=$q&rsz=large&hl=ru&start=$start");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_REFERER, "http://$sireUrl/");
$body = curl_exec($ch);
curl_close($ch);

//Ответ получили, в принципе, зада выполнена :)
$json = json_decode($body);
//На этом этапе можно сделать print_r($json) и все станет понятно
//Но что бы в smarty было проще разобрать результаты, можно преобразовать его в следующий вид

$search = array();

//Результаты поиска
if (count($json -> responseData -> results) == 0) { //если ничего не найдено
  $search['result'] = false;
} else {
  foreach ($json -> responseData -> results as $v) {
    $search['result'][] = array(
      'GsearchResultClass'   => $v -> GsearchResultClass,
      'unescapedUrl'       => $v -> unescapedUrl,
      'url'           => $v -> url,
      'visibleUrl'       => $v -> visibleUrl,
      'cacheUrl'         => $v -> cacheUrl,
      'title'         => $v -> title, //заголовок найденого документа (индексируется ведь не только html-странички)
      'titleNoFormatting'   => $v -> titleNoFormatting,
      'content'         => $v -> content //выдержка из текста документа
    );
  }
}

//Список ссылок на остальные результаты поиска
if (count($json -> responseData -> results) == 0) { //если ничего не найдено
  $search['pages'] = false;
} else {    
  $url = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REDIRECT_URL'].'?q='.$reqData['q'];
  foreach ($json -> responseData -> cursor -> pages as $v) {
    $search['pages'][] = array(
      'start'   => $v -> start,
      'startUrl'  => $url.'&start='.$v -> start,
      'label'   => $v -> label
    );
  }
}

//Общая информация о результатах поиска
$currentPageIndex = $json -> responseData -> cursor -> currentPageIndex;
$search['info'] = array(
  'q'            => $reqData['q'],
  'estimatedResultCount'   => $json -> responseData -> cursor -> estimatedResultCount,
  'moreResultsUrl'    => $json -> responseData -> cursor -> moreResultsUrl,
  'currentPageIndex'     => $currentPageIndex,
  'currentLabel'      => $currentPageIndex + 1,
  'startResult'      => $currentPageIndex * 8 + 1,
  'endResult'        => ($currentPageIndex * 8 + 1) + count($search['result']),
  'next'          => (count($search['pages']) > $currentPageIndex + 1) ? $search['pages'][$currentPageIndex + 1]['startUrl'] : false,
  'prev'          => ($currentPageIndex) ? $search['pages'][$currentPageIndex - 1]['startUrl'] : false
);
  

//Все готово
MySmarty::get() -> assign('search', $search);

?>


* This source code was highlighted with Source Code Highlighter.


SMARTY


Использую ограничители «{{» и «}}» что бы отличать smarty от javascript

{{if !$search.result}}
  По запросу <b> {{$search.info.q}} </b> ничего не найдено или в данным момент поисковый сервис недоступен.
{{else}}
  Результаты <b>{{$search.info.startResult}} - {{$search.info.endResult}}</b> из примерно <b>{{$search.info.estimatedResultCount}}</b> для <b>{{$search.info.q}}</b>
  <br />
  <br />

  {{section name=i loop=$search.result}}
    <a href="{{$search.result[i].url}}">{{$search.result[i].title}}</a><br />
    {{$search.result[i].content}}
    <br />
    <br />

  {{/section}}

  <br/>

  {{if $search.info.prev}}
    <a href="{{$search.info.prev}}">Предыдущая</a>    
  {{/if}}
  
  
  {{section name=i loop=$search.pages}}
    {{if $search.info.currentLabel == $search.pages[i].label}}
      {{$search.pages[i].label}}
    {{else}}
      <a href="{{$search.pages[i].startUrl}}">{{$search.pages[i].label}}</a>
    {{/if}}
  {{/section}}
  
  {{if $search.info.next}}
        <a href="{{$search.info.next}}">Следующая</a>
  {{/if}}

{{/if}}


* This source code was highlighted with Source Code Highlighter.


Вот и получили хороший поиск по любого рода данным (html,doc,pdf и остальные документы по которым ищет google).

Так же есть удобный инструмент для тестов Google Ajax Api Playground.

Хабралюди, если вы в курсе, подскажите пожалуйста, как обстоят дела с соглашениями об использовании этого поискового API. Должен ли я на страничке с результатами указывать что пользуюсь поиском google, или делать еще что-либо подобное?

Спасибо за внимание.

P.S. Это мой первый пост на хабре, если что-то сделал не так скажите, исправлю :)
Tags:
Hubs:
+6
Comments 6
Comments Comments 6

Articles