|
  Building dynamic WML sites
Andres
Baravalle
Cellular phones supporting
WAP are slowly, but constantly spreading. Therefore,
it could be time for you to start building your WML
pages to access internet databases. As such, we will
show you how to build PHP/WML pages to access a MySQL
database which contains professors' receiving hours
and exams timetables for a University. I'm testing
a beta service of this kind, prepared with Vitaveska
Lanfranchi, at www.scidecom.it.
There are some things you need
to know before starting. First, we are assuming that:
- You have correctly installed PHP and MySQL, and
you have some experience in programminng with both languages.
Your database needs to be properly installed as
well.
- You have some knowledge of SQL; I suggest reading Database
Normalization and Design Techniques.
- You are running Apache and you can write .htaccess
files; or you are running IIS and you can add mappings
(or you can ask the system administrator to do
it for you).
- You have some experience with WML; I suggest
reading Introduction
to WML, Apache, and PHP.
The first step is telling your
server to process WML pages with PHP. Let's see how
to do it.
Setting up the server
If you are using Apache, you
have to look for a .htaccess file in your home directory.
Then, you need to write the following lines in it:
<limit get post>
AddType application/x-httpd-php3 .wml
</limit>
If you don't have a file .htaccess,
simply write these lines in a text editor and save
the result as .htaccess in your home directory.
If you are using IIS instead,
you have to do the same you did when you installed
PHP in your server: look at the mappings of .php
and .php3 extensions and do the same for .wml extension.
Commonly you will find PHP mapped
onto:
C:\php\php4isapi.dll
or
C:\php\php.exe
Preparing to work
If you use Microsoft OS, you
can install the NOKIA Development Kit. It checks
for your syntax and lets you preview your WML pages
with a phone-like user interface. Moreover, the kit
comes equipped with useful documentation about WML
and WMLScript. This helps if you don't have a mobile
phone with WAP support, or if you can't use a WAP
gateway.
To download it, you have first
to register as a wap
developer. Remember that you need the Java2
Runtime Enviroment. However, any text editor
is fine for writing your pages.
Before writing any PHP/WML
code, you need to set up your MySQL tables.
The database is structured in
4 tables.
- table
professors contains data about professors
- table
subjects contains data about subjects
- table
exams contains data about exams
- table
teach contains the relations between
the professors and their subjects
Write the code below after establishing
a MySQL connection.
CREATE TABLE professors (
Id int(11) DEFAULT '0' NOT NULL auto_increment,
Surname varchar(24) NOT NULL,
Name varchar(24) NOT NULL,
Email varchar(48) DEFAULT 'Not avaliable',
Cod_course varchar(16) DEFAULT 'Not avaliable',
Consulting_hour varchar(128) DEFAULT 'Not avaliable',
Consulting_place varchar(128) DEFAULT 'Not avaliable',
PRIMARY KEY (Id)
);
These lines specifiy the structure
of table professors. Id is the field for associating
an unique identifier with each professor and is the
key of the table. The other fields, Surname, Name, Email specifies
the surname, the name and the e-mail address for
each professor. Cod_course assumes unique
values identifying the subjects. Finally, Consulting_hour and Consulting_place specify
the receiving time and the place for receiving.
CREATE TABLE subjects (
Subject varchar(96) NOT NULL,
Cod_Subject varchar(24) NOT NULL,
Cod_number varchar(12) NOT NULL,
PRIMARY KEY (Cod_subject )
);
Subject is the name of the subject, Cod_subject is
the field containing the unique name adopted by the
University for the subject and is the key of the
table. Cod_number is a numeric field containing
a number grouping different courses on the same subject.
CREATE TABLE exams (
Cod_Subject varchar(24) NOT NULL,
Id int(11) NOT NULL,
Date date DEFAULT '0000-00-00',
Time time DEFAULT '00:00:00',
Room varchar(64),
Test varchar(16) DEFAULT 'Oral'
);
Cod_subject again contains
the unique name adopted by the University for the
subject,Id is the unique identifier for the
professors, Date, Time, and Room,
record the date, the time and the place where exams
will take place; Test is for the type of the
exam (written, oral, or anything else).
CREATE TABLE teach (
Cod_Subject varchar(16) NOT NULL,
Id int(11) DEFAULT '0' NOT NULL,
PRIMARY KEY (Id, Cod_subject )
);
In table teach the two
fields form the key and are necessary to know who
is teaching what.
The next step is filling the
database with some data, which you can do by yourself.
Writing PHP/WML code
Now we write our first PHP/WML
page which we call index.wml
<?php
Header("Content-type: text/vnd.wap.wml"); Header("Cache-Control: no-cache, must-revalidate"); Header("Pragma: no-cache"); echo ("<?xml version='1.0'?>"); ?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml" > <wml> <card id="card1" title="UNITO/Database"> <p> You can search for professors' consulting hours or for examinations timetables. <select name="choice" value="1" title="Research"> <option value="exams_data">Examinations timetables</option> <option value="consulting_data">Consulting hours</option> </select> <do type="text" label="Go"> <go method="get" href="index2.wml#card2"> <postfield name="choice" value="$(choice)" /> </go> </do> </p> </card> </wml>
The first line tells the browser
accessing the page what kind of MIME type are sent.
Without the header command, the browser could not
understand what kind of content is coming. Moreover,
with this line you are not forced to set a particular
extension for your files. This is very useful if
you plan to write multimodal pages, with a script
that checks the device or its capabilities and returns
WML or HTML according to the type of browser.
Check whether PHP is installed
with short tags enabled. If yes, every time you write
a declaration like <?xml
version='1.0'?>, embed it into PHP code
to avoid confusion.
The rest of the code of this
page simply lets you search for examinations timetables
or consulting hours. The choice is recorded into
variable $choice.
The next page is called index2.wml
and allows you to decide whether you want to query
the database by subject or by surname.
<?php
Header("Content-type: text/vnd.wap.wml"); Header("Cache-Control: no-cache, must-revalidate"); Header("Pragma: no-cache"); echo ("<?xml version='1.0'?>"); ?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml"> <wml> <card id="card2" title="Kind of research"> <p> <?php echo ("You are checking ");
if ($choice == "exams_data") { echo (" examinations timetables.<br />\n"); } else if ($choice == "consulting_data") { echo (" consulting hours.<br />\n"); } else { echo ("I don't know what and there is some problem.<br />\n"); } ?> </p> <p> You can search by surname (either exact or partial) or by subject (either exact or partial).<br /> Select the kind of research.</p> <p> <select name="<?php echo ("$choice");?>" value="surname" title="research"> <option value="surname"> professor's name</option> <option value="subject"> subject</option> <do type="text" label="Go"> <go method="get" href="index3.wml#card3"> <?php echo ("<postfield name=\"$choice\" value=\"$"."$choice"."\"/>"); echo ("<postfield name=\"choice\" value=\"$choice\"/>"); ?> </go> </do> </p> </card> </wml>
Again the decision is stored into variable $choice.
Now the user must input the data as specified in the
next file, index3.wml. We ask the user to insert the name of a subject
or the surname of a professor. Look how variables are sent, in this
page and in the previous. The syntax is pretty complex, but it lets
you handle all the whole process, with only a few files.
<?php
Header("Content-type: text/vnd.wap.wml"); header("Cache-Control: no-cache, must-revalidate"); header("Pragma: no-cache"); echo "<?xml version='1.0'?>"; ?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml" > <wml> <card id="card3" title="Name"> <?php
echo ("<p>Insert ");
if (${$choice} == "surname") { echo ("professor's surname (or part of it).<br />\n"); } else if (${$choice} == "subject") { echo ("the subject (or part of it).<br />\n"); } else { echo ("Maybe there is some problem.<br />\n"); }
echo ("<input type=\"text\" name=\"${$choice}\" />");
?> <do type="text" label="Go"> <go method="get" href="query.wml"> <?php
echo ("<postfield name=\"$choice\" value=\"$"."$choice"."\"/>");
echo ("<postfield name=\"${$choice}\" value=\"$"."${$choice}"."\"/>");
?> </go> </do> <p> </p> </card> </wml>
Writing the query
This file is the one responsible for handling the query. It's name is query.wml
and we will analyze it more in depth.
<?php
Header("Content-type: text/vnd.wap.wml"); printf("<?xml version=\"1.0\"?>\n"); printf("<!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\" " ."\"http://www.wapforum.org/DTD/wml_1.1.xml\" >\n"); printf("<wml>\n");
// The next lines are used to build // the sql query for receiving hours:
$consulting_tables = "(professors left join teach on (professors.Id = teach.Id), subjects)"; $consulting_columns = "professors.Surname, professors.Name, subjects.Subject , "; $consulting_columns .= "subjects.Cod_number, professors.Consulting_hour, professors.Consulting_place"; $consulting_query= "subjects.Cod_Subject = teach.Cod_subject ";
// The next lines are used to build the // sql query for examination timetables:
$exams_tables= "(exams left join professors ON (exams.Id = professors.Id), subjects)"; $exams_columns= "subjects.Subject , subjects.Cod_number, professors.Surname, "; $exams_columns.= "professors.Name, exams.Date, exams.Time, exams.Room, exams.Test"; $exams_query= "exams.Cod_Subject = subjects.Cod_Subject ";
// The next lines are used to add options to the sql query for examination timetables:
if ($exams_data) {
switch($exams_data) { case "subject": $exams_query.= " and subjects.Subject like '%$subject%'"; break; case "surname": $exams_query.= " and professors.Surname like '%$surname%'"; break; } }
// The next lines are used to to add options to the sql query for receiving times:
if ($consulting_data) { switch($consulting_data) { case "subject": $consulting_query .= " and subjects.Subject like '%$subject%'"; break; case "surname": $consulting_query.= " and professors.Surname like '%$surname%'"; break; } }
// handles the connection with database
function connect($tables, $data, $condition_passed) { // // put your password and username in next line //
$db = mysql_pconnect("localhost","***","***");
// put your database name in next line
mysql_select_db("lanfranchi_co_uk",$db);
$sql = "SELECT $data FROM $tables WHERE $condition_passed order by professors.Surname"; $result = mysql_query($sql,$db); return $result; }
// this function writes the wml code for receiving hours
function consulting_print($consulting_result) { global $file; printf("<card id=\"card1\" title=\"hours\">\n"); printf("<p>Receiving hours</p>\n"); while ($myrow = mysql_fetch_row($consulting_result)) { printf("<p>$myrow[0], $myrow[1]</p>\n"); printf("<p>$myrow[2]</p>\n"); printf("<p>$myrow[3]</p>\n"); printf("<p>$myrow[4]</p>\n"); printf("<p>$myrow[5]</p>\n"); } printf("</card>\n"); }
// this function writes the wml code for examination timetables
function print_exams($exams_result) { global $file; printf("<card id=\"card1\" title=\"hours\">\n"); printf("<p>Examinations hours</p>\n"); while ($myrow = mysql_fetch_row($exams_result)) { printf("<p>$myrow[2], $myrow[3]</p>\n"); printf("<p>$myrow[0]</p>\n"); printf("<p>$myrow[1]]</p>\n"); printf("<p>$myrow[4], $myrow[5]</p>\n"); printf("<p>$myrow[7]</p>\n"); printf("<p>$myrow[6]</p>\n"); } printf("</card>\n"); }
// checks if you selected reciving hours or examination //timetables, connects to the database and calls the //function to the write wml code
if ($consulting_data) { $connection_result = connect($consulting_tables, $consulting_columns, $consulting_query); consulting_print($connection_result); } if ($exams_data) { $connection_result = connect($exams_tables, $ exams_columns, $ exams_query); print_exams($connection_result); } printf("</wml>\n");
?>
The End
We have finished. Your first PHP/WML pages are ready to get the data
from your MySQL database.
-- Andres
|