AJAX a knižnica článkov s fulltextovým vyhľadávaním – práca s článkami
V tomto č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.
Súbor clanky.class.php
K zlepšeniu funkcionality systému bola vytvorená trieda Clanky
. V triede Clanky
sú atribúty polí (premenné) typu public
a private
, metódy (funkcie), konštruktor a deštruktor. Trieda Clanky
slúži ostatným súborom na vytváranie a spracovanie výsledkov databázy. Oddelenie vytvárania vrstiev funkcionality aplikácie umožňuje flexibilné a rozšíriteľné aplikácie.
<?php
// zavedie súbor pre ošetrenie chýb a konfiguračný súbor
require_once(‚error.php‘);
require_once(‚config.php‘);
// definuje triedu Clanky
class Clanky {
// premenná pre požiadavku SQL
public $mQuery;
// premenná určujúca stĺpce pre match
public $mCol;
// ovládač dátabaze
private $mMysqli;
// konštruktor triedy
function __construct() {
$this->mMysqli = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_DATABASE);
}
// deštruktor triedy
function __destruct() {
if ($this->mMysqli) $this->mMysqli->close();
}
// funkcia pre spracovanie fulltextového vyhľadávania
public function createFullText($query, $col,$whole) {
// zakódovanie dát pre ich bezpečné použitie v príkazoch SQL
$query = $this->mMysqli->real_escape_string(trim($query));
$col = $this->mMysqli->real_escape_string($col);
$whole = $this->mMysqli->real_escape_string($whole);
// zadefinovanie stĺpcov pre match vo fulltextovom vyhľadávaní
$this->mCol = $col == ‚autori‘ ? $col : $col.‘,nazov‘;
// zostavenie požiadavky pre SQL
switch ($col){
case ‚autori‘:
$query = ereg_replace(quotemeta(„+|-|*|~|\\|\“|<|>|(|)“),““,$query);
$this->mQuery = ‚“‚.$query.'“‚;
break;
case ‚abstrakt‘:
$words = explode(‚ ‚,$query);
for ($i=0;$i<count($words);$i++) if (Strlen($words[$i])>3 && !$whole) $words[$i] .= ‚*‘;
$this->mQuery = implode(‚ ‚,$words);
break;
}
}
// vráti počet článkov
public function getNumRows ($query) {
if ($result = $this->getQuery($query)) {
$numRows = $result->num_rows;
$result->close();
}
return $numRows;
}
// vráti celkový počet článkov pri SELECT COUNT(*)
public function getNumAllRows ($query) {
if ($result = $this->getQuery($query)) {
$row = $result->fetch_row();
$result->close();
}
return $row[0];
}
// vráti obsah riadku
public function getRow ($query) {
if ($result = $this->getQuery($query)) {
$row = $result->fetch_array(MYSQLI_ASSOC);
$result->close();
}
return $row;
}
// vráti príkaz SQL
public function getQuery($query) {
return $this->mMysqli->query($query);
}
}
}
?>
Pri tvorbe databázy používame objektove orientovanú knižnicu mysqli, ktorá bola implementovaná v PHP 5. Pomocou konštruktora __construct
sa vytvára inštancia triedy a automaticky vytvára spojenie na databázu. Deštruktor __destruct
sa volá po zániku objektu a tým sa uzatvára databázové spojenie. Pre vysvetlenie činnosti fulltextového vyhľadávania odporúčame preštudovať si článok Erika Hoffmanna Fulltextové vyhľadávanie v MySQL – prax.
Súbor clanky-top.php
Súbor clanky-top.php sa načíta v súbore clanky.php a pomocou globálnych premenných $_POST
, respektíve $_GET
, nastavuje $_SESSION
. Následne inicializuje premenné $_question
, $_col
, $_whole
, $_lim
a $_skip
použité v súbore clanky.php.
<?php
// zavedie súbor pre ošetrenie chýb a pre triedu Clanky
require_once(‚error.php‘);
require_once(‚clanky.class.php‘);
// štart session
session_start();
// nastaví session podľa $_POST a $_GET
if (isset($_POST[‚q‘])) {
$_SESSION[‚values‘][‚s_query‘] = $_POST[‚q‘];
if (isset($_POST[‚whole‘])) $_SESSION[‚values‘][‚s_whole‘] = ‚yes‘; else $_SESSION[‚values‘][‚s_whole‘] = “;
if (isset($_POST[‚col‘])) $_SESSION[‚values‘][‚s_col‘] = $_POST[‚col‘];
}
if (isset($_GET[‚skip‘])) $_SESSION[‚values‘][‚s_skip‘] = sprintf(„%d“, $_GET[‚skip‘]);
// nastavi premenne pre subor clanky.php
$_query = $_SESSION[‚values‘][‚s_query‘]; $_col = $_SESSION[‚values‘][‚s_col‘];
$_skip = $_SESSION[‚values‘][‚s_skip‘]; $num = $_SESSION[‚values‘][‚s_num‘];
$_whole = $_SESSION[‚values‘][‚s_whole‘]; $lim = ROWS_PER_VIEW;
?>
Súbor clanky.php
Súbor clanky.php je vyvolaný klasicky kliknutím na button „Články“ vo vstupnom formulári úvodnej stránky. Metódou POST sú odovzdané parametre formulára a zobrazia sa nájdené články v databáze. Počet zobrazených článkov je nastavený v súbore config.php. V prípade väčšieho počtu článkov ako je nastavený počet zobrazených článkov, môžeme pomocou príkazov v spodnom riadku zobrazovať nasledujúce stránky s článkami. Súčasne s XHTML kódom stránky sa načítavajú súbory clanky.css a abstrakt.js.
<?php
// zavedie súbory pre ošetrenie chyb a clanky_top.php.
require_once(‚error.php‘);
require_once(‚clanky_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ánky</title>
<link rel=“stylesheet“ type=“text/css“ href=“clanky.css“ />
<script type=“text/javascript“ src=“request.js“></script>
<script type=“text/javascript“ src=“abstrakt.js“></script>
</head>
<body>
<h1>Knižnica článkov</h1>
<div id=“wrap“>
<h2>Články</h2>
<?php
// vytvorí inštanciu triedy Clanky
$_sql = new Clanky();
// spracuje premenné pre fulltextové vyhľadávanie
$_sql->createFullText($_query, $_col, $_whole);
$query = „SELECT *“;
// vytovorí SQL pre zobrazenie všetkých článkov
if ($_query == ‚?‘) {
$num = $_SESSION[‚values‘][‚s_count‘];
$query .= “ FROM clanky“;
}
// vytvorí SQL pre zobrazenie článkov pre fulltextové vyhľadávanie, min. tri znaky
elseif (StrLen(trim($_query)) > 3) {
if ($_col != ‚autori‘) $query .= „,MATCH($_sql->mCol) AGAINST(‚$_sql->mQuery‘ IN BOOLEAN MODE) AS vaha“;
$query .= “ FROM clanky WHERE MATCH($_sql->mCol) AGAINST(‚$_sql->mQuery‘ IN BOOLEAN MODE)“;
// poradie pri fulltextovom vyhľadávaní je určené váhou
if ($_col != ‚autori‘) $query .= “ ORDER BY vaha DESC“; else $query .= “ ORDER BY nazov ASC“;
// zobrazenie mena autora alebo kľúčových slov
if ($_col != ‚autori‘) echo ‚<p>Kľúčové slová: ‚; else echo ‚Autor: ‚;
echo ‚<i>‘.htmlspecialchars($_query).'</i></p>‘;
// ak počet riadov nebol načítaní v JS
if ($num == -1) $num = $_sql->getNumRows($query);
// ošetrenie chýb
if ($num == 0) echo ‚<p>Ľutujeme, ale nenašiel sa žiaden článok!</p>‘;
}
else echo ‚<p>Ľutujeme, ale nezadali ste meno autora alebo kľúčové slová (minimálne štyri znaky)!</p>‘;
if ($num > 0) {
echo ‚<p id=“top“>Počet článkov: <b>‘.$num.'</b>‘;
if (trim($_query) != ‚?‘) echo ‚ z ‚.$_SESSION[‚values‘][‚s_count‘];
if ($num > $lim) echo ‚ <span>Stránka: <b>‘.sprintf(„%d“,($_skip/$lim+1)).'</b> (‚.sprintf(„%d“, ($num-1)/$lim+1).‘)</span>‘;
echo ‚</p> <ul>‘;
$query .= “ LIMIT $_skip, $lim“;
// vykoná SQL požiadavku
if ($result = $_sql->getQuery($query)) {
while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
// tvorba zoznamu článkov
echo ‚<li><span><a href=“abstrakt.php?id=‘.$row[„ID“].'“ title=“Abstrakt-html“><img src=“icon_html.png“ alt=“Abstrakt-html“ /></a><a href=“‚.$row[„clanok“].'“ title=“Článok-pdf“><img src=“icon_pdf.png“ alt=“Článok-pdf“ /></a></span>‘.$row[„autori“].‘: <em>‘.$row[„nazov“].‘, </em>‘.$row[„kde“].'<div /></li>‘;
echo ‚</ul>‘.“\n“;
$result->close();
}
}
else echo ‚<p>Ľutujeme, ale sa nepodarilo pripojiť na server, pokúste sa opäť!</p>‘;
// tvorba foot
echo ‚<p class=“foot“>‘;
if ($num>$_skip && $_skip>=$lim) echo ‚<a href=“clanky.php?skip=‘.($_skip – $lim).'“>predchádzajúca stránka</a>‘;
echo ‚ <a href=“./“>úvodná stránka</a> ‚;
if ($num>$_skip+$lim) echo ‚<a href=“clanky.php?skip=‘.($_skip + $lim).'“>nasledujúca stránka</a>‘;
echo ‚</p>‘.“\n“;
?>
</div>
</body>
</html>
Súbor abstrakt.js
Pomocou JavaScriptu a objektu XMLHttpRequest môžeme načítať – bez opätovného načítania stránky – obsah vybraného abstraktu kliknutím na príslušnú ikonku. Súbor abstrakt.js spolupracuje so súborom abstrakt.php. V prípade asynchrónneho spojenia okrem parametra id
článku posielame metódou GET aj parameter xml=1
.
//spustí po načítaní stránky
window.onload = function() {
// vytvorí odkazy na <li>
var lis = document.getElementsByTagName(‚li‘);
// pri stlačení ikonky abstraktu definuje odkaz
for (var i=0; i<lis.length; i++) {
lis[i].getElementsByTagName(‚a‘)[0].onclick = function() {
// vytvorí inštanciu objektu XMLHttpRequest
var request = requestObj ();
// vytvorí odkaz na element <div>
var div = this.parentNode.parentNode.lastChild;
// pri kliknutí sa obsah abstraktu schová
div.onclick = function () {this.innerHTML = „“; this.className = „“;}
// ak je objekt XMLHttpRequest
if(request) {
// metóda pre spracovanie odpovede zo servera
request.onreadystatechange = function() {
// ak prebehlo všetko v poriadku
if (request.readyState == 4) {
if (request.status == 200) {
try {
// extrahuj XML zo servera
var rootXML = request.responseXML.documentElement;
// ošetrenie chyby pre Firefox
if (rootXML.nodeName == „parsererror“) throw(„“);
// načítanie dát do elementu <div>
else div.innerHTML = rootXML.firstChild.data;
}
// sprava pre uzivatela v pripade chyby servera
catch (e) {div.innerHTML = „Ľutujeme, nepodarilo sa pripojiť na server, pokúste sa opäť!“;}
} else {div.innerHTML = „Ľutujeme, nepodaril sa prenos zo servera, pokúste sa opäť!“}
}
}
// zobraz obsah abstraktu
div.className = „show“;
// správa pre prípad pomalého Internetu
if (div.innerHTML == „“) div.innerHTML = „<b>Abstrakt</b> sa načítáva…“;
// na serveri spusti stránku abstrakt.php s parametrami id a xml
request.open(„GET“, this.href+“&xml=1″, true);
// pošle žiadosľ na server
request.send(null);
}
// v prípade neúspechu vráti true a vykoná sa pôvodný odkaz v HTML
else {return true;}
// v prípade úspešného načítania abstraktu vráti false
return false;
}
}
}
Každý článok používa vlastný objekt XMLHttpRequest. Toto najjednoduchšie riešenie zabezpečuje, že nedôjde k strate požiadavky na server. Pri spracovaní odozvy sa postupuje štandardným spôsobom. Chyby sa vychytávajú pomocou metódy try/catch
v prehliadačoch MSIE a Opera. Firefox generuje hlásenie o chybe v koreni súboru XML, ktorý nazýva „parsererror“. V prípade Firefoxu vygeneruje sa pomocou throw
výnimka, ktorá sa zachytí ako u ostatných prehliadačoch v catch
. V prípade korektnej odozvy servera sa obsah abstraktu načíta do kontajnera div
pomocou innerHTML
. V prípade pomalého pripojenia k internetu sa objavuje správa, že sa súbor načítáva.
Súbor abstrakt.php
Súbor abstrakt.php v úvode načíta súbor clanky.class.php pre načítanie obsahu abstraktu z databázy. Súbor spracúva požiadavky generované JavaScriptom. V prípade, ak prehliadač nemá implementovaný objekt XMLHttpRequest alebo je zakázaný JavaScript, súbor abstrakt.php je volaný odkazom priamo zo stránky clanky.php. V prvom prípade je generovaný súbor typu XML, v druhom prípade súbor typu XHTML, ktorý je zobrazený samostatne v okne prehliadača.
<?php
// zavedie súbory pre ošetrenie chýb a triedy Clanky
require_once(‚error.php‘);
require_once (‚clanky.class.php‘);
// štart session
session_start();
// nastavenie premených podľa $_GET
if (isset($_GET[‚id‘])) $user_id = $_GET[‚id‘]; else $user_id = 0;
if (isset($_GET[‚xml‘])) $user_xml = $_GET[‚xml‘]; else $user_xml = 0;
// vytvorí inštanciu triedy Clanky
$_sql = new Clanky();
// tvorba SQL príkazu
$query = sprintf(„SELECT autori,nazov,abstrakt FROM clanky WHERE ID = %d“, $user_id);
// vykoná prikaz SQL
$row = $_sql->getRow ($query);
// ak požiadavka je cez AJAX, tvorba XML súboru
if ($user_xml==1) {
header(‚content-type: text/xml‘);
echo ‚<?xml version=“1.0″ encoding=“utf-8″ ?><abstrakt><![CDATA[‚.$row[„abstrakt“].‘]]></abstrakt>‘;
}
// inak tvorba XHTML súboru
else {
// . . . . . .
// generuje sa XHTML abstraktu
// . . . . . . . . . .
}
?>
V prípade vytvorenia súboru XHTML sa súčasne načíta aj abstrakt.css, ktorý určuje vzhľad stránky.
Súbor o_kniznici.html
Klasický statický hypertextový súbor slúži ako zdroj informácii o použití knižnice. Súčasne sa načíta aj súbor o_kniznici.css, ktorý určuje vzhľad stránky.
Záver
Klasické statické stránky sa stávajú minulosťou. V súčasnosti sa dostávajú do popredia interaktívne stránky, využívajúce PHP script na strane servera a JavaScript spojený s objektom XMLHttpRequest na strane klienta. Internetové aplikácie sa svojím správaním približujú desktopovým aplikáciám, ale ich realizácia býva spravidla jednoduchšia. Klasické statické stránky sa používajú najmä ako informačné stránky.
Mohlo by vás také zajímat
-
ZONER Webmail jako první v Česku přináší BIMI s VMC
11. července 2024 -
Jak se chránit před podvody na internetu – část 1
8. října 2024 -
Praktické rady na zabezpečení redakčního systému WordPress
27. února 2023
Nejnovější
-
Jak rozšířit úložiště Macu za pětinovou cenu?
16. prosince 2024 -
Nové trendy v doménách pro osobní projekty – DIY, LIVING a LIFESTYLE
9. prosince 2024 -
Jak chránit webové stránky před Web/AI Scrapingem
27. listopadu 2024 -
Jaký monitor je nejlepší k novému Macu Mini?
25. listopadu 2024