Ud∞lejme si vlastnφ chat

Pou₧itφ jazyka PHP si nynφ ukß₧eme na komplexn∞jÜφm p°φklad∞, kter²m bude jednoduch² chat. Chaty pat°φ mezi velice oblφbenΘ webovΘ aplikace, a krom∞ ceny nenφ d∙vod proΦ by nem∞ly b²t oblφbenΘ i ve svΘ wapovΘ podob∞.

Na zaΦßtku prßce s chatem si musφ ka₧d² u₧ivatel zvolit svΘ jmΘno, pod kter²m chce vystupovat. Nßsledujφcφ p°φklad obsahuje jedno vstupnφ pole, do kterΘho lze zadat jmΘno. JmΘno je jako parametr odeslßno skriptu chat.php, kter² se starß o samostatnΘ chatovßnφ.

P°φklad 2. Strßnka pro p°ihlßÜenφ do chatu û login.php

<? 
  Header("Content-Type: text/vnd.wap.wml");
  echo '<?xml version="1.0"?>';
?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
          "http://www.wapforum.org/DTD/wml_1.1.dtd">
<wml>
  <card title="Vitej v chatu!">
    <p>
      Pred vyuzitim chatu si musite zvolit jmeno: 
      <input name="jmeno"/>
    </p>
    <p>
      <a href="chat.php?jmeno=$(jmeno)#c2">Vstoupit</a>
    </p>
  </card>
</wml>          

Za URL adresou je p°φtomen jeÜt∞ text `#c2'. Ten zp∙sobφ to, ₧e po naΦtenφ vygenerovanΘ strßnky se rovnou zobrazφ karta s identifikßtorem (atribut id) c2.

Ne₧ se pono°φme do zdrojovΘho k≤du jßdra chatu, vysv∞tlφme si zßkladnφ princip, na kterΘm pracuje. JednotlivΘ zprßvy v chatu se uklßdajφ do textovΘ souboru û jedna zprßva na jednΘ °ßdce. Na zaΦßtku °ßdky je v₧dy jeÜt∞ ulo₧eno jmΘno autora zprßvy.

Skript chat.php se pak musφ postarat o nßsledujφcφ v∞ci:

P°φklad 3. Jßdro chatu û chat.php

<? 
  Header("Content-Type: text/vnd.wap.wml");
  echo '<?xml version="1.0"?>';
    
  if ($zprava!="")
  {
    if (File_Exists("zpravy.txt"))
    {
      $zpravy = File("zpravy.txt");
    }

    $fp = FOpen("zpravy.txt", "w");
    FPutS($fp, "<b>$jmeno:</b> $zprava\n");
    for ($i=0; $i<10; $i++)
    {
      FPutS($fp, $zpravy[$i]);
    }
    FClose($fp);
  }

?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
          "http://www.wapforum.org/DTD/wml_1.1.dtd">
<wml>
  <card title="W@P Chat" id="c1">
    <p>
      Zprava: <input name="zprava"/><br/>
      <a href="chat.php?jmeno=$(jmeno)&amp;zprava=$(zprava)&amp;r=<?
        echo UniqId("")?>#c2">Odeslat</a>
      <br/>
      <a href="chat.php?jmeno=$(jmeno)&amp;r=<?echo UniqId("")?>#c2">
        Obnovit
      </a>
    </p>
  </card>
  <card title="W@P Chat" id="c2" 
        ontimer="chat.php?jmeno=$(jmeno)&amp;r=<?echo UniqId("")?>#c2">
    <timer value="200"/>
    <do type="accept" label="Nova zprava">
      <go href="#c1"/>
    </do>
    <?
      $fp = FOpen("zpravy.txt", "r");
      while ($radka = FGetS($fp, 512))
      {
        echo "<p>$radka</p>";
      }
      FClose($fp); 
    ?>
  </card>
</wml>          

Poj∩me si nynφ rozebrat jednotlivΘ Φßsti skriptu. Na zaΦßtku testujeme, zda nßm p°iÜla n∞jakß zprßva, kterou mßme p°idat do seznamu zprßv. Test provßdφme pomocφ podmφnky if. Podmφnka za if musφ b²t v₧dy v zßvorkßch, k porovnßnφ dvou hodnot slou₧φ operßtor ==.

Pokud u₧ivatel n∞jakou zprßvu odeslal, musφme ji zapsat na zaΦßtek souboru. Pokud soubor existuje, naΦteme ho do pole:

if (File_Exists("zpravy.txt"))
{
  $zpravy = File("zpravy.txt");
}

Funkce File_Exists() testuje, zda zadan² soubor existuje. Pokud soubor existuje naΦteme ho pomocφ funkce File() do pole s nßzvem $zpravy. Pole je specißlnφ druh prom∞nnΘ, kterß m∙₧e obsahovat vφce hodnot najednou. V naÜem p°φpad∞ bude obsahovat ka₧d² prvek pole jeden °ßdek souboru a tedy i jednu zprßvu.

Nßsledujφcφ k≤d p°idß na zaΦßtek souboru novou zprßvu a za nφ nakopφruje ty starÜφ.

K otev°enφ souboru pro zßpis slou₧φ funkce FOpen(). Jako jejφ parametry musφme zadat nßzev souboru a re₧im otev°enφ (w oznaΦuje otev°enφ pro zßpis). Funkce nßm vrßtφ identifikßtor souboru, kter² se pak pou₧φvß v dalÜφch funkcφch.

Aby Ülo do souboru na serveru zapisovat, musφme mu sprßvn∞ nastavit prßva. To jednoduÜe ud∞lßme tak, ₧e vytvo°φme prßzdn² soubor zpravy.txt a nakopφrujeme ho mezi skripty na serveru. Pak mu zm∞nφme atributy tak, aby do n∞j Ülo zapisovat. M∙₧eme k tomu pou₧φt nap°φklad Internet Explorer. Vybere soubor a otev°eme si jeho vlastnosti. V nich pak nastavφme prßvo zßpisu pro vÜechny (viz obrßzek 2).

Obrßzek 2. Nastavenφ prßv pro datov² soubor

Novou °ßdku do souboru m∙₧eme zapsat pomocφ funkce FPutS(). Prvnφm parametrem je identifikßtor souboru a druh²m zapisovan² °et∞zec.

FPutS($fp, "<b>$jmeno:</b> $zprava\n");

Do souboru vlo₧φme jednu °ßdku, okolo jmΘna vlo₧φme element b, za n∞j pak samotnou zprßvu. Konec zprßvy ukonΦφme pomocφ znaku \n, kter² v textov²ch °et∞zcφch zastupuje konec °ßdky.

Nynφ za novou zprßvu zapφÜeme starÜφ zprßvy. Zapisuje se p°itom pouze deset nejnov∞jÜφch zprßv.

for ($i=0; $i<10; $i++)
{
  FPutS($fp, $zpravy[$i]);
}

P°φkaz for slou₧φ k opakovanΘmu provedenφ urΦit²ch p°φkaz∙, podobn∞ jako ve WMLScriptu. Kopφrujeme v₧dy jen poslednφch deset zprßv, aby nßm soubor se zprßvami zbyteΦn∞ nenar∙stal.

Nakonec soubor zav°eme pomocφ funkce FClose().

Dßle ve skriptu nßsleduje statick² WML k≤d pro prvnφ kartu. Ta obsahuje pouze vstupnφ pole pro zadßnφ zprßvy a odkazy pro odeslßnφ novΘ zprßvy a pro ruΦnφ obnovenφ zobrazen²ch zprßv.

Jako souΦßst odkazu se p°edßvß i paramet r. Jeho hodnotu generujeme dynamicky pomocφ PHP funkce UniqId(). Ta vracφ v₧dy jedineΦnΘ Φφslo. Tφm ₧e bude souΦßstφ URL adresy unikßtnφ Φφslo, bude v₧dy prohlφ₧eΦ naΦφtat obsah strßnky znovu ze serveru a nebude se jej sna₧it naΦφst z vyrovnßvacφ pam∞ti. ZobrazenΘ zprßvy budou v₧dy aktußlnφ. Uveden² zp∙sob je nejjednoduÜÜφ a nejspolehliv∞jÜφ cestou k zakßzßnφ keÜovßnφ strßnek.

Odkaz je na konci dopln∞n znaky `#c2', aby se v₧dy skoΦilo na druhou kartu s v²pisem zprßv.

Obrßzek 3. P°ihlßÜenφ k chatu

Druhß karta slou₧φ k v²pisu zprßv. Je na nφ nastaven ΦasovaΦ na dvacet sekund. Po tΘto dob∞ je karta automaticky znovu naΦtena (pomocφ atributu ontimer). Zobrazφ se tak p°φpadnΘ novΘ zprßvy od dalÜφch u₧ivatel∙.

Na kart∞ je rovn∞₧ tlaΦφtko, kterΘ umo₧nφ p°echod na prvnφ kartu a zadßnφ novΘ zprßvy.

Obrßzek 4. Chatovßnφ v plnΘm proudu

Nakonec vypφÜeme skriptem do karty vÜechny zprßvy. Pomocφ funkce FOpen() si nejprve otev°eme soubor, tentokrßte pro Φtenφ (re₧im r). Pomocφ funkce FGetS() Φteme jednotlivΘ °ßdky ze souboru. NeΦteme vÜak najednou nikdy vφce ne₧ 512 znak∙ (druh² parametr). NaΦtenou °ßdku uklßdßme do prom∞nnΘ $radka. Dokud nenφ °ßdka prßzdnß provßd∞jφ se p°φkazy uvnit° t∞la p°φkazu while.

P°φkaz

echo "<p>$radka</p>";

vypφÜe do generovanΘ WML strßnky jeden odstavec, kter² bude obsahovat prßv∞ p°eΦtenou zprßvu ze souboru. Nakonec soubor op∞t uzav°eme.

⌐ Ji°φ Kosek 2000-2001