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.

Žádný příspěvek v diskuzi

Odpovědět