AJAX a knižnica článkov s fulltextovým vyhľadávaním – základ rozhrania

11. dubna 2007

Knižnica článkov je jednoduchá internetová aplikácia na fulltextové vyhľadávanie abstraktov, článkov publikovaných vo vedeckých a odborných časopisoch alebo v zborníkoch konferencií či workshopov.

Môžete si stiahnuť základné súborypozrieť výsledok na demonštračnej databáze.

Databáza informácií o článkoch

Základné informácie o článkoch sú v elektronickej forme uložené v tabuľke databázy MySQL5 alebo vyššej:

CREATE TABLE clanky (
  ID int not null auto-increment primary key,
  autori varchar (200),
  nazov varchar (200),
  kde varchar (200),
  abstrakt text,
  clanok varchar (100),
  FULLTEXT (autori, nazov, abstrakt)
) ENGINE=MyISAM CHARSET utf8 [COLLATE utf8_slovak_ci];

V tabuľke clanky máme stĺpce, ktorých význam vyplýva z ich názvu. Stĺpec abstrakt obsahuje základné údaje o článku a v stĺpci clanok je odkaz na článok vo formáte PDF (vytlačený článok z internetu sa potom podobá originálu v časopise alebo v zborníku konferencie). Fulltextové vyhľadávanie pracuje len so stĺpcami typu varchar alebo text a tabuľka musí byť typu MyISAM. Výraz v hranatých zátvorkách nie je povinný, ak ho nepoužijeme, collation (porovnanie textov) sa automaticky nastaví na utf8_general_ci.

Súbor error.php

Zmyslom tohto súboru je zachytenie chybových správ generovaných v PHP5 a generovanie vlastnej priateľskej správy pre užívateľa.

<?php
// nastaví uživateľskú metódu ošetrenia chýb na error_handler
set_error_handler(‚error_handler‘,E_ALL);
function error_handler(){
  // zmaže všetky výstupy, ktoré boli generované
  if (ob_get_length()) ob_clean();
  // pošle priateľskú správu
  echo „Ľutujeme, nepodarilo sa pripojiť na server, pokúste sa opäť!“;
  // ukonči PHP
  exit();
}
?>

set-error-handler nastavíme novú funkciu pre ošetrenie chýb. Keď dôjde k chybe, použitím ob_clean zmažeme výstup, generujeme pomocou echo správu pre užívateľa a ukončíme činnosť PHP. Použitím súboru error.php v ostatných súboroch typu *.php eliminujeme lokálne ošetrenie chýb pomocou die, čím kód týchto súborov bude jednoduchší a prehľadnejší.

Súbor config.php

Dáta uložené v súbore slúžia na nastavenie konfigurácie databázy.

<?php
// definuje dáta pre dátabazu
define(‚DB_HOST‘,’localhost‘);
define(‚DB_USER‘,’root‘);
define(‚DB_PASSWORD‘,“);
define(‚DB_DATABASE‘,“);
// definuje počet zobrazených riadkov (článkov) na stránke
define(‚ROWS_PER_VIEW‘, 4);
?>

Súbor index-top.php

Tento súbor sa načíta v súbore index.php a inicializuje premenné $_SESSION [´values´], ktoré sa používajú aj v súbore clanky.php.

<?php
// zavedie súbor pre ošetrenie chýb a triedy Clanky
require_once(‚error.php‘);
require_once(‚clanky.class.php‘);
// naštartuje session
session_start();
// inicializuje session
if (!isset($_SESSION[‚values‘])) {
  $_sql = new Clanky();
  $query = „SELECT COUNT(*) FROM clanky“;
  $_SESSION[‚values‘][‚s_count‘] = $_sql->getNumAllRows ($query);
  $_SESSION[‚values‘][‚s_col‘] = ‚abstrakt‘; $_SESSION[‚values‘][‚s_num‘] = -1;
  $_SESSION[‚values‘][‚s_skip‘] = 0; $_SESSION[‚values‘][‚s_query‘] = “;
  $_SESSION[‚values‘][‚s_whole‘] = “;
}
if ($_SESSION[‚values‘][‚s_query‘] == ‚?‘) $_SESSION[‚values‘][‚s_query‘] = “;
if ($_SESSION[‚values‘][‚s_skip‘] != 0) $_SESSION[‚values‘][‚s_skip‘] = 0;
$check = ‚checked = „checked“‚;
?>

Súbor index.php

Úvodná stránka sa zobrazuje pomocou súboru index.php. Najprv načítame súbor index-top.php a potom samotný XHTML kód stránky. Jadrom kódu XHTML je formulár, ktorý slúži na nastavenie parametrov pre vyhľadávanie článkov. Súčasne s XHTML kódom sa načítajú súbory request.jskniznica.jskniznica.css. Vzhľad stránky určujú kaskádové štýly v súbore kniznica.css. XHTML kód stránky je navrhnutý tak, aby pri vypnutých autorských štýloch zobrazenie stránky bolo korektné.

<?php
require_once(‚index_top.php‘);
echo ‚<?xml version=“1.0″ encoding=“utf-8″ ?>‘.“\n“;
?>
<!DOCTYPE html PUBLIC „-//W3C//DTD XHTML 1.0 Strict//EN“ „http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd“>
<html xmlns=“http://www.w3.org/1999/xhtml“ xml:lang=“sk“ lang=“sk“>
<head>
  <meta http-equiv=“Content-Type“ content=“text/html; charset=utf-8″ />
  <meta http-equiv=“Content-Language“ content=“sk“/>
  <title>Knižnica článkov</title>
  <link rel=“stylesheet“ type=“text/css“ href=“kniznica.css“ />
  <script type=“text/javascript“ src=“request.js“></script>
  <script type=“text/javascript“ src=“kniznica.js“></script>
</head>
<body>
  <h1>Knižnica článkov</h1>
  <div id=“wrap“>
  <!– formular –>
  <form action=“clanky.php“ method=“post“>
  <p><b>Hľadať:</b>
  <input type=“radio“ id=“au“ name=“col“ value=“autori“ <?php if ($_SESSION[‚values‘][‚s_col‘] == ‚autori‘) echo $check; ?> />
  <label for=“au“>medzi autormi |</label>
  <input type=“radio“ id=“ab“ name=“col“ value=“abstrakt“ <?php if ($_SESSION[‚values‘][‚s_col‘] == ‚abstrakt‘) echo $check; ?> />
  <label for=“ab“>kľúčové slová v názve a v abstrakte</label>
  <span id=“wh“> [ <input type=“checkbox“ id=“whole“ name=“whole“ value=“yes“ <?php if ($_SESSION[‚values‘][‚s_whole‘] == ‚yes‘) echo $check; ?> />
  <label for=“whole“> celé slová ]</label></span></p>
  <p class=“query“><input type=“text“ size=“50″ id=“q“ name=“q“ value=“<?php echo $_SESSION[‚values‘][‚s_query‘]; ?>“ />
  <input class=“submit“ type=“submit“ value=“Články»“ /><span id=“num“> </span></p>
  </form>
  </div>
  <!– foot –>
  <p class=“foot“><a href=“o_kniznici.html“ title=“Informácie o knižnici“>O knižnici</a> <a href=“http://fyzika.utc.sk/~jamnic/fyzikalnicek/contact.php“ title=“Kontakt na autora“>Kontakt</a></p>
  <noscript><p>Odporúčame Vám povoliť JavaScript!</p></noscript>
</body>
</html>

Súbor request.js

Objekt XMLHttpRequest umožňuje kódu JavaScriptu vytvárať asynchrónne požiadavky (bez opätovného načítania stránky) na http server. Objekt XMLHttpRequest bol pôvodne implementovaný v ActiveX firmou Microsoft ešte v roku 1999. Vďaka používaniu Google bol objekt XMLHttpRequest implementovaný ako natívny objekt aj v iných prehliadačoch, ale až 18. 2. 2005 publikoval Jesse James Garrett článok Ajax: A New Approach to Web Applications, v ktorom popísal použitie objektu XMLHttpRequest a použil skratku AJAX (Asynchronous JavaScript and XML).

function requestObj () { // získa objekt XMLHttpRequest
  var req = false;;
  try { req = new XMLHttpRequest();} // IE 7, Firefox, Opera 8…
  catch(e) {
    try { req = new ActiveXObject(‚Microsoft.XMLHTTP‘); } // IE 5.x, IE 6
    catch(e) {}
  }
  return req; // vráti vytvorený objekt
};

V našom prípade na vytvorenie inštancie objektu XMLHttpRequest používame funkciu requestObj. Využívame pritom dvojicu metód OOP JavaScriptu try a catch. Výnimky vytvorené v try (zkús) sú zachytené v catch (zachyť).

Súbor kniznica.js

Objekt XMLHttpRequest bol použitý v Google Suggest na automatické dokončovanie, čo je sofistikovaná obdoba funkcie autocomplete. V našom prípade fulltextového vyhľadávania bol objekt XMLHttpRequest využitý na určenie počtu článkov, ktoré vyhovujú priebežnému nastaveniu parametrov vo formulári.

// počet článkov
function getNumber() {
  // prevedie sa vtedy, ak objekt nie je zaneprázdnený
  if(request.readyState == 4 || request.readyState == 0) {
    // tvorba parametrov pre SQL
    var col = encodeURIComponent(document.getElementById(‚au‘).checked ? ‚autori‘:’abstrakt‘);
    document.getElementById(‚wh‘).style.visibility = col==’autori‘ ? ‚hidden‘ : ‚visible‘;
    var whole = encodeURIComponent(document.getElementById(‚whole‘).checked ? ‚yes‘:“);
    var query = encodeURIComponent(document.getElementById(‚q‘).value);
    // na serveri spustí stránku kniznica.php
    request.open(‚POST‘, ‚kniznica.php‘, true);
    request.setRequestHeader(‚Content-Type‘,’application/x-www-form-urlencoded‘);
    // definuje metódu pre spracovanie odpovede zo severa
    request.onreadystatechange = handleResponse;
    // pošle žiadost na server
    request.send(‚col=’+col+’&q=’+query+’&whole=’+whole);
  }
  // ak spojenie je zaneprázdnené, pokús sa opäť o pol sekundy
  else {
    if (timeout) clearTimeout(timeout);
    timeout = setTimeout(‚getNumber()‘,500);
  }
};
// spustí sa automaticky po prijatí správy zo servera
function handleResponse() {
  // test ukoncenia transakcie
  if (request.readyState == 4) {
    if (request.status == 200) {
      // spracuj odozvu
      var response = request.responseText;
      var num = document.getElementById(‚num‘);
      // ignoruj chybu
      if (response != 0 && response.length>0 && response.length<3)
        num.innerHTML = „Počet článkov: <b>“+response+“</b>“;
      else num.innerHTML = „“;
      // opakuj cyklus
      if (timeout) clearTimeout(timeout);
      timeout = setTimeout(‚getNumber()‘,500);
    }
  }
};
// vytvorí inštanciu objektu XMLHttpRequest
var request = requestObj ();
var timeout;
// spustí po načítaní stránky
window.onload = function () {
  var q = document.getElementById(‚q‘);
  // zameria fokus
  q.focus();
  // ak existuje objekt XMLHttpRequest a funkcia encodeURIComponent spustí cyklus
  if (request && window.encodeURIComponent) {
    // spustí aj po načítaní znaku
    q.onkeyup = getNumber;
    setTimeout(‚getNumber()‘,100)
  }
};

JavaScript v súbore kniznica.js nám spolu s objektom XMLHttpRequest zabezpečujú v spolupráci so súborom kniznica.php asynchrónne spojenie klient/server.

Základom je funkcia getNumber, kde sa pomocou DOM načítajú parametre formulára a po nastavení spojenia pomocou metódy open pošlú metódou send parametre na http server. Odozva servera je spracovaná funkciou handleResponse.

Po kontrole kompletnosti prenosu testujeme dĺžku reťazca, ktorý je uložený v responseText. V reťazci by mal byť počet článkov, ktoré vyhovujú nastaveným parametrom formulára. V prípade chyby sa v responseText objaví prázdny text. Počet článkov sa zobrazí vo formulári, ak responseText obsahuje najmenej jeden znak a menej ako tri znaky.

Po načítaní stránky index.php sa spustí kód JavaScriptu, ktorý zamieri fokus na textový vstup formulára a spustí cyklicky sa opakujúce spojenie so serverom s pol sekundovým intervalom. Spojenie so serverom sa spustí aj po načítaní znaku vo vstupnom textovom riadku vo formulári.

Súbor kniznica.php

Súbor clanky.class.php sa načíta v úvode súboru kniznica.php. Ďalej sa nastavia vnútorné premenné podľa parametrov v premenných zaslaných pomocou objektu XMLHttpRequestkniznice.js. Po vytvorení inštancie triedy Clanky zistíme počet článkov v databáze, ktoré vyhovujú parametrom nastavených vo formulári. Počet článkov sa uloží do globálnej premennej a odošle pomocou echo späť ako odozva servera.

<?php
// štart session
session_start();
// zavedenie súboru pre ošetrenie chýb a triedy Clanky
require_once (‚error.php‘);
require_once (‚clanky.class.php‘);
// do premenných $_query, $_col a $_whole uloží dáta z premennej $_POST
if (isset($_POST[‚q‘])) $_query = $_POST[‚q‘]; else $_query = “;
if (isset($_POST[‚col‘])) $_col = $_POST[‚col‘]; else $_col = ‚abstrakt‘;
if (isset($_POST[‚whole‘])) $_whole = $_POST[‚whole‘]; else $_whole = “;
// ak požiadavka SQL má viac ako tri znaky
if (StrLen(trim($_query))>3) {
  //vytvorí inštanciu triedy Clanky
  $_sql = new Clanky();
  $_sql->createFullText($_query, $_col, $_whole);
  // zostaví príkaz SQL
  $query = „SELECT autori,nazov,abstrakt FROM clanky WHERE MATCH($_sql->mCol) AGAINST(‚$_sql->mQuery‘ IN BOOLEAN MODE)“;
  // prevedie príkaz SQL
  $num = $_sql->getNumRows($query);
  // uloží do session a vráti počet článkov
  $_SESSION[‚values‘][‚s_num‘] = $num;
  echo $num;
}
// ignoruje chybu
else {
  $_SESSION[‚values‘][‚s_num‘] = -1;
  echo “;
}
?>

Podrobnejšie informácie o spolupráci AJAXu a PHP môžete získať napríklad v knihe AJAX a PHP – tvoříme interaktivní webové aplikace profesionálně, ktorú vydalo nakladateľstvo Zoner Press.

V pokračovaní článku bude uvedený popis súborov, ktoré umožňujú zobrazenie článkov podľa parametrov nastavených vo vstupnom formulári v úvodnej stránke.

Předchozí článek navrchol.sk
Další článek Stínování textu
Štítky: Články

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *