Telefonní seznam s wapovým rozhraním

Jak skloubit PHP, SQL a WML dohromady nám demonstruje následující příklad jednoduché wapové aplikace, která umožní prohledávání telefonního seznamu a přidávání nových záznamů. Přidání nových záznamů bude navíc umožněno jen osobám se znalostí specifického jména a hesla.

Příklad 2. Vyhledávání v telefonním seznamu – seznam.php

<? 
  Header("Content-Type: text/vnd.wap.wml");
  echo '<?xml version="1.0" encoding="iso-8859-2"?>';
?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
          "http://www.wapforum.org/DTD/wml_1.1.dtd">
<wml>
  <card title="Telefonní seznam" id="vstup">
    <p>
      Zadejte hledané jméno:<br/>
      <input name="jmeno"/><br/>
      <a href="seznam.php?jmeno=$(jmeno)#vysledek">Hledej</a>
    </p>
    <p><a href="novy.php">Nové číslo</a></p>
  </card>
  <? if (IsSet($jmeno)): ?>
  <card title="Telefonní seznam" id="vysledek">
    <?
      MySQL_PConnect("localhost", "jkj", "heslo");
      MySQL_Select_DB("jkj");
      $vysledek = MySQL_Query("SELECT * FROM Telefony 
                               WHERE Jmeno LIKE '%$jmeno%'
                               ORDER BY Jmeno");

      echo "<p>Počet nalezených záznamů: " . 
           MySQL_Num_Rows($vysledek) . "</p>\n";                               
                               
      while ($zaznam = MySQL_Fetch_Array($vysledek))
      {
        echo "<p><b>" . $zaznam['Jmeno'] ."</b>: ";
        echo "<a href='wtai://wp/mc;" . $zaznam['Telefon'] . "'>" . 
             $zaznam['Telefon'] . "</a><br/>";
        echo $zaznam['Email']. "</p>\n";
      }
    ?>
    <p><a href="#vstup">Nové hledání</a></p>
  </card>
  <? endif ?>
</wml>

Samotné prohledávání v seznamu umožňuje skript seznam.php. Při prvním volání skript vygeneruje stránku s jednou kartou, která umožňuje zadání hledaného jména a spuštění hledání (obrázek 3).

Obrázek 3. Karta pro zadání podmínky pro vyhledávání

Zadání podmínky pro hledání způsobí zaslání nového požadavku na webový server. Ten vygeneruje novou stránku, která kromě karty pro zadání výsledků, obsahuje kartu, do které se vygenerují výsledky hledání v databázi (obrázek 4).

Obrázek 4. Karta s výsledkem vyhledávání

Využívá se přitom několika funkcí, které ještě neznáme. Funkce MySQL_Num_Rows() vrací počet záznamů, které jsou výsledkem SQL příkazu SELECT. Jako parametr musíme funkci předat identifikátor výsledku, který vrací funkce MySQL_Query().

Pro sekvenční zpracování výsledku používáme funkci MySQL_Fetch_Array(). Ta postupně vrací jednotlivé záznamy výsledku. Každý záznam je vrácen jako asociativní pole, které umožňuje následně velice jednoduše přistupovat k jednotlivým položkám záznamu. Po zpracování všech záznamů funkce vrací false, a cyklus while pro zpracování výsledku se ukončí.

Uvnitř cyklu kombinujeme statický WML kód s hodnotami z databáze. Z každého záznamu vygenerujeme jméno, telefonní číslo (včetně odkazu využívajícího WTAI) a emailovou adresu. Dostaneme WML kód s následující strukturou:

<p><b>Jan Novák</b>: 
<a href='wtai://wp/mc;+420212345678'>+420212345678</a><br/>
novak@mail.cz</p>

Na kartě s vyhledáváním je odkaz, který volá další skript novy.php. Ten umožňuje vložení nového záznamu. Stránka obsahuje jen několik vstupních polí a odkaz, který tato pole odešle dalšímu skriptu, jenž provede samotné přidání do databáze.

Příklad 3. Přidání nového záznamu – novy.php

<? 
  require "./auth.php";
  echo '<?xml version="1.0" encoding="iso-8859-2"?>';
?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" 
              "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
  <card title="Nový uživatel">
    <do type="prev" label="Zpět">
      <prev/>
    </do>
    <p>Jméno: <input name="jmeno" type="text" format="*M"
		     emptyok="false"/><br/>
       Telefon: <input name="telefon" type="text" format="*N"
		     emptyok="false"/><br/>
       E-mail: <input name="email" type="text" format="*m"
		     emptyok="true"/>
    </p>
    <p>
      <anchor>Přidej
	<go href="novy-insert.php">
	  <postfield name="jmeno" value="$(jmeno)"/>
	  <postfield name="telefon" value="$(telefon)"/>
	  <postfield name="email" value="$(email)"/>
	</go>
      </anchor>
    </p>
  </card>
</wml>

Ve většině aplikací samozřejmě nechceme, aby data mohl modifikovat kdokoliv. V těchto případech bývá aplikace ochráněna jménem a heslem, bez jehož znalosti se na chráněné stránky nedostaneme. Protokol WSP obsahuje obdobu HTTP autentifikace. Mikroprohlížeči tedy můžeme zaslat speciální hlavičky, které si vyžádají zadání jména a hesla od uživatele.

Potřebný kód je uložen ve skriptu auth.php, který načítáme na začátku chráněných stránek. Skript testuje jméno a heslo zaslané uživatelem. Pokud jméno není admin a heslo traktor, pošle skript zpět klientovi žádost o zadání jména a hesla a skript se ukončí (příkazem exit). Dorazí-li správné jméno a heslo, skript se neukončí a můžeme generovat WML stránku obvyklým způsobem.

Příklad 4. Ochránění stránky jménem a heslem – auth.php

<?
  if (!IsSet($PHP_AUTH_USER) or
      !($PHP_AUTH_USER=="admin" && $PHP_AUTH_PW=="traktor")):
    Header("HTTP/1.0 401 Unauthorized");
    Header("WWW-Authenticate: Basic realm=\"telseznam\"");
    Header("Content-Type: text/vnd.wap.wml");
    echo '<?xml version="1.0" encoding="iso-8859-2"?>';
?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
          "http://www.wapforum.org/DTD/wml_1.1.dtd">
<wml>
  <card title="POZOR!!!">
    <p>Pokus o neoprávněný přístup!</p>
    <p>Pro přístup na tyto stránky potřebujete znát jméno a heslo.</p>
    <p><a href="<?echo "$SCRIPT_NAME?r=" . UniqId("")?>">Přihlásit
         znovu</a></p>
  </card>
</wml>
<?
    exit;
  endif;

  Header("Content-Type: text/vnd.wap.wml");
?>

Pro konkrétní server si mikroprohlížeč jméno a heslo pamatuje, takže je pak uživatel nemusí zadávat na každé chráněné stránce, ale jen na úvodní.

Obrázek 5. Přidání nového záznamu do telefonního seznamu

Jméno, telefonní číslo a e-mail, které vyplní uživatel, jsou odeslány skriptu novy-insert.php. Ten se postará o přidání do databáze. Jen poznamenejme, že hodnoty vstupních polí jsou ve skriptu dostupné v proměnných s odpovídajícím názvem – můžeme je snadno doplnit do SQL příkazu.

Příklad 5. Vložení nového záznamu – novy-insert.php

<? 
  require "./auth.php";
  echo '<?xml version="1.0" encoding="iso-8859-2"?>';
?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" 
              "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
  <card title="Nový uživatel">
    <do type="prev" label="Přidat daląího">
      <prev/>
    </do>
    <?
      MySQL_PConnect("localhost", "jkj", "heslo");
      MySQL_Select_DB("jkj");
      $vysledek = MySQL_Query("INSERT INTO Telefony (Jmeno, Telefon, Email)
                               VALUES ('$jmeno', '$telefon', '$email')");
      if ($vysledek)
        echo "<p>Nový záznam byl úspěąně přidán.</p>";
      else
        echo "<p>Při přidávání záznamu doąlo k chybě.</p>";
    ?>
    <p><a href="seznam.php">Zpět do seznamu</a></p>
  </card>
</wml>

Celou aplikaci si můžete vyzkoušet na adrese http://www.yo.cz/pages/jkj/seznam.php.

© Jiří Kosek 2000-2001