PHP & Hosted Applications

PHP 4 is a server-side scripting language that runs on almost any OS used for web hosting. It also supports numerous web servers including Microsoft's Internet Information Server (IIS), Apache, and AOL Server, and it has native support for multiple database engines


January 01, 2001
URL:http://www.drdobbs.com/database/php-hosted-applications/184404437

Jan01: PHP & Hosted Applications

Ahmad is an independent consultant and writer. He can be contacted at ahmad@ apicalconsulting.com.


So Why PHP?


PHP is a server-side scripting language, most often used to spice up static web pages served from UNIX-based Apache servers. However, PHP 4 (the current version, available at http://www.php.net/) runs on almost any operating system used for web hosting. PHP also supports numerous web servers, including Microsoft's Internet Information Server (IIS), Apache, and AOL Server, and it has native support for multiple database engines such as Microsoft SQL Server, Oracle, MySQL, and mSQL, to name a few.

PHP is embedded in HTML code (or vice versa) using special tags. The web server invokes the PHP engine to process the PHP code before it sends the output to the browser with whatever HTML is already on the page. The browser sees only an HTML page.

PHP is well suited for performing system-level functions, such as file and folder manipulation. It can access databases to retrieve, insert, modify, and delete data from a database server. PHP can interpret form data and perform actions based on form requests. It can also encrypt data, handle cookies, generate images on the fly, perform session management, and perform identification, authentication, and authorization functions — all on the fly.

The Making of a Hosted Application

Additionally, PHP 4 can be used as part of a hosted application on remote servers. Many such hosted applications can be developed using back-end databases, a business layer written in PHP, and a front-end developed in DHTML and JavaScript.

To illustrate how you can use PHP to create hosted applications, I'll present in this article an electronic survey application that can be hosted on your servers and used by remote clients to survey end users. A global enterprise with scattered departments might use an application like this to survey employees for benefits information or customers for product feedback and market research. Such an application does not have to be limited to this particular usage, however. It can be used in voting, opinion polling, product registration, or similar pursuits.

Although the hosted app I present here uses the MySQL database, you can also use Microsoft SQL Server and Oracle with PHP. If you use a lot of stored procedures, complex subqueries, or data integrity via foreign-key constraints, you should probably opt for something other than MySQL. Since this application does not use any of the aforementioned functions, MySQL is a good choice.

The PHP code consists of three main pieces:

When you first access the system to create a new survey, you are prompted to enter a name, description, and the total number of questions in the survey. This information is collected in a form and submitted to a PHP page called "step2.php." Rather than being a slow new process invocation, PHP is invoked as a Server API (SAPI) application. PHP is good at processing information sent by users (the values of complex form selects, radio buttons, and other form elements). Listing One, which shows the relevant code of the first page in the application, produces a simple form to collect user input with a JavaScript validation function to ensure users entered all required data in the appropriate format. The real action occurs in step2.php, at which time all of the form input elements are readily available as variables in the script. Thus, the code in step2.php (see Listing Two) can access the variables $survey_name, $survey_description, and $survey_questions without extra logic to handle the form's data. In contrast, if you are using ASP/VBScript, you will need to access the form variables using the built-in Request() object and QueryString collection.

The next step is to create a list of questions for users to answer, each with a question type. This application lets users create free text questions or multiple-choice questions. The multiple-choice questions can accept either one answer (radio buttons) or multiple answers (check boxes). You should track the number of questions needed, the text for every question, the type of question (before dynamically generating other HTML forms to input the text questions), and the multiple choices where applicable. The available approaches for holding the information include:

With PHP, all of these are valid options. With its simple database interface, connection pooling, and persistent connections, you can efficiently store the information in the database and carry over a survey ID from one request to another. Whenever the information is needed, it can be picked up from the database.

With PHP 4's Session Management interface, the process is even more straightforward. You have to register your form variables (which PHP created on the fly to start with) as session variables, and all the information is accessible in all PHP scripts invoked in that same session. You can then carry the information over in the form's request collection from one page to another. Step2.php takes that approach in Listing One.

If you have never used server-side scripts, a brief explanation is in order. The tags <? and ?> are used to delimit PHP code. Lines outside those tags are normal HTML. PHP code can be intermixed with HTML. Regardless of its place in the file, all PHP code gets executed on the server before the HTML page is generated. The printf() function is used to generate output that will become part of the final HTML sent to the browser. The semicolons (;) and the braces ({}) are part of the syntax familiar to C/C++ programmers. You may be confused initially by the dollar ($) signs. They are just the way variables are named in PHP. Just remember to prefix all variable names with $.

All form variables from the previous form appear immediately in the new script. Also, the three hidden input elements in the new form ensure that the $survey_questions, $survey_name, and $survey_description variables are carried across without any special code or logic to handle them. The loop generates one select statement and one text input for every question in the survey. Users specify the type of the question and the number of choices available per question.

The next step, step3.php (Listing Three), follows the same concept. PHP takes care of passing all the form input values to your script. Two nested loops generate the form input elements needed to collect all the information. The outer loop iterates through the questions, generating form input elements for the text of each question. The inner loop iterates through the multiple choices per question, if applicable, thus generating form input elements for the text of each choice. A puzzle that you may encounter is what to name the form elements holding the text for the multiple choices. PHP 4 has a useful feature that lets you name those variables using 2D array notation, for example:

printf ("<input type=checkbox name= check_box[$i][$j]>");

This resultant HTML form has a line that looks something like the following:

<input type=checkbox name=check_box [0][1]>

HTML has no problem with this notation, even though PHP 3 (and other scripting languages) would not know how to handle the variable in the target form. With PHP 4, however, you have a variable called $check_box[0][1] that holds the input value. Since that variable is an actual array element, you can use a nested loop to iterate through all its elements.

After all the data are collected, it is time to insert the values into the database. PHP has built-in support for a large number of databases as well as connectivity to any ODBC-enabled database. (Perhaps a future PHP version will introduce a common set of database functions to isolate the code from the actual DBMS being used. Until then, you have to make calls that are specific to your DBMS.)

For example, Listing Four creates an entry in a table called "Survey" within a MySQL database called "Surveys." Examples 1, 2, and 3 show three MySQL tables created for this application. The ID is an automatically generated ID for the survey. Under Microsoft SQL Server, this type of field is called Identity; under Oracle, you will need to create another object called Sequence, but the idea is the same. Name and Description are both strings of variable size. MySQL limits the size to 255 characters: Other databases have a more liberal limit.

There are two mistakes to avoid here. Commonly, users choose a small limit for the size of a varchar field. Because this is a variable-length field, you only use space equivalent to the length of the actual string used (plus some overhead), and not the upper limit. Thus in most cases, it does not make sense to use anything smaller than 255. If you are in doubt, keep it at 255 and enforce a length limit in your code that is easier to change in the future. The other problem you have to be aware of is the internationalization of dates. Recently, an application of mine started failing in England when the date generated by my ActiveX components failed to insert into a SQL database after the user changed the date format on the server. Make sure you use either the built-in database date functions to insert the current date, or use functions based on the locale if you are generating the date values in your code.

The other two tables holding the survey data are Questions and Choices, as shown in Examples 2 and 3. You join the Survey with the Questions in the code based on the SurveyID field in the Questions table. Similarly, you join the Choices with Questions using the QuestionID field.

All the data can be inserted using code similar to the mysql_query() code in Listing Four. By making the ID an auto_increment primary key, you get MySQL to provide you with the last inserted ID using the PHP function mysql_insert_id().

The flip side of the application lets users take and complete the survey. Users key in the ID of the survey, and the application performs a select statement against the database. A loop on the result set generates an HTML form with elements for every question. The form gets submitted to a final PHP script that takes the answers and inserts them into an Answers table that may look something like Example 4.

The listings and examples presented here form the basis of a complete survey application. I left some of the code for your imagination, but it is easy to see how you can develop a full-blown online application using PHP and a back-end database. PHP 4 compiles all the code in a page before executing it, making it fast, efficient, and perfect for such applications. Another advantage is that you will not encounter "syntax error" surprises because all of those are detected at compile time and not at run time.

Conclusion

For developing more complex applications, PHP 4 can invoke Java objects, and in Win32 environments, it can create and invoke COM objects. This functionality is similar to what ASP provides through the Server.CreateObject method. For example, under ASP, if you decide to create a separate COM component to perform database queries and hold large result sets, you can then create the object and call functions in it in a fashion similar to the code in Listing Five. In short, PHP 4 provides the same functionality for COM and Java objects. For example, Listing Six shows how code from Listing Five looks in PHP. This lets you reuse existing components, as well as move complex code to components if you so wish.

DDJ

Listing One

<form method="post" name="create_survey" action="step2.php" 
onsubmit="return validate();">
    <table border=0 cellspacing=2 cellpadding=2>
        <tr>
            <th> Please enter the survey's name </th>
            <td> <input type="text" name="survey_name"> </td>
        </tr>
        <tr>
            <th> Please enter a short description </th>
            <td> <input type="text" name="survey_description"> </td>
        </tr>
        <tr>
            <th> Please enter the number of questions in the survey </th>
            <td> <input type="text" name="survey_questions"> </td>
        </tr>
        <tr> 
            <td> <input type="Submit" Value="Create Survey">
        </tr><
/table>    <
/form>

Back to Article

Listing Two

<html><
head><
/head><
body><
form id="create_questions" name="create_questions" 
                                          action="step3.php" method=post><
?
    printf ("<input type='hidden' name=survey_questions 
                                          value=$survey_questions>");
    for ($i=0;$i<$survey_questions;$i++) {
        $j = $i+1;
        printf ("Select Question Type for Question $j <p>");
        printf ("<select name='questions_type[$i]'>");
        printf ("<option value=0> Free Text Answer");
        printf ("<option value=1 selected> Radio Button Answer");
        printf ("<option value=2> Check Box Answer");
        printf ("</select>");
        printf ("<br>If Radio Button or Check Box:<br> <dl> ");
        printf ("<dd> Number of Choices ");
        printf ("<input type=text length=5 name=choices[$i] value=3><br>");
        printf ("<dd><input type=checkbox name=isCheck[$i] value=selected>");
        printf ("Provide an Other option</dl>");
        printf ("<hr color=blue>");
    }
?><
input type="submit" value="Goto Step 3"><
/form><
/body><
/html>

Back to Article

Listing Three

<html><
body>
    <form method=post name=create id=create action="createit.php">
    <?
        printf ("<input type='hidden' name=survey_questions 
                                               value=$survey_questions>");
        $choice_counter=0;
        for ($i=0;$i<$survey_questions;$i++) {
            echo "<br>";
            $j=$i+1;
            echo "<big>Question #$j is: </big> ";
            echo "<input type=text id=question_text[$i] 
                                               name=question_text[$i]>\n";
            echo "<input type='hidden' name=choices[$i] 
                                               value=$choices[$i]>\n";
            printf ("<input type=hidden id=questions_type[$i] 
                      name=questions_type[$i] value=$questions_type[$i]>\n");
            switch ($questions_type[$i]) {
                case 0:
                    echo "<p>";
                    break;
                case 1:
                    printf("<br>  ");
                    for ($counter=0;$counter<$choices[$i];$counter++) {
                        printf ("Choice #$counter: <input type=text 
                            id=choice_text[$choice_counter] 
                            name=choice_text[$choice_counter]>\n");
                        if ($counter && ($counter % 2 == 0)) echo "<br>\n";
                        $choice_counter++;
                    }
                    break;
                case 2:
                    printf("<br>  ");
                    for ($counter=0;$counter<$choices[$i];$counter++) {
                        printf ("Choice #$counter: <input type=text 
                            id=choice_text[$choice_counter] 
                            name=choice_text[$choice_counter]>\n");
                        if ($counter && ($counter % 2 == 0)) echo "<br>\n";
                        $choice_counter++;
                    }
                    break;
                default:
                    echo $questions_type[$i];
                    break;
            }
            echo "<hr color=red>";
        }
    ?>
    <input type="submit" Value="Create Survery" >
    </form><
/body><
/html>

Back to Article

Listing Four

$stmt = "insert into surveys.survey (name,lastupdate,DateCreated,OwnerID, ";
    $stmt = $stmt . "Description,isClosed) values 
                                            ('$survey_name',now(),now(),0";
    $stmt = $stmt . ",'$survey_description',0)";
    if (!(mysql_query($stmt)) {
{
        printf ("Failed in Creating the Survey Entry...");
        exit();
    }

Back to Article

Listing Five

<%
            Dim myObject
            Set myObject = Server.CreateObject("MyProject.MyClass")
            Dim myString
            myString = myObject.GetDataBaseName
            Response.Write "The Database name is " & myString
        %>

Back to Article

Listing Six

        <?
            $myObject = new COM("MyProject.MyClass");
            $myString = $myObject->GetDataBaseName();
            echo "The Database name is $myString";
        ?>


Back to Article

Jan01: PHP & Hosted Applications


Create table survey (ID not int not null auto_increment,
    name varchar(255), LastUpdate date, DateCreated Date, 
    OwnerID number, Description varchar(255), 
    IsClosed smallint, primary key(ID));

Example 1: The Survey table.

Jan01: PHP & Hosted Applications


Create Table Questions (ID int not null auto_increment,
    SurveyID int not null, QuestionType smallint,
    QuestionText varchar(255), NumberOfChoices smallint, 
    isRequired smallint, primary key (ID), index (SurveyID));

Example 2: The Question table.

Jan01: PHP & Hosted Applications


Create Table Choices (ID int not null auto_increment,
    QuestionID int not null, Text varchar(255),
    primary key (ID), index (QuestionID));

Example 3: The Choices table.

Jan01: PHP & Hosted Applications


Create Table Answers (SurveyID number, QuestionID number,
    ChoiceSelected smallint, AnswerText varchar(255));

Example 4: The Answer table.

Jan01: So Why PHP?

So Why PHP?

There are several options available for server-side web scripting. Here, I limit my discussion to the four that I use on a daily basis — PHP, ASP/VBScript, Perl, and Java Server Pages (JSP). What makes PHP any better or worse than these alternatives? I'll start with JSP.

JSP is Java code intermixed with HTML code. It can execute only on a server that supports JSP and Java servlets. Some web servers do not support Java servlets, and many ISPs or ASPs do not offer it as an option in all configurations. Generally, the development cycle in a Java environment is considerably longer than developing in PHP. The second issue with JSP is that its implementation and future are married to the futures of Java, Java Servlets, and Enterprise JavaBeans. All of these change constantly, mostly for the better. However, the changes are not always backwardly compatible. As any web developer knows, you don't only have to worry about your own code, but also about the technologies that you are using. Using JSP simply means that you have three more layers of software wherein things can go wrong due to no fault of your own code.

The second alternative is Perl, which is a powerful scripting language used not only for web applications, but also for many standalone programs, system administration programs, and software management programs. There's a huge amount of Perl software ready for use. One problem with Perl, however, is that on most web servers, it is executed as an out-of-process CGI program, making it slower and less efficient (PerlScript being the most notable exception).

The major advantage of Perl over PHP is that you can use Perl for various system administration tasks. This may change in the near future since PHP 4 has a superior new scripting engine. The new engine (known as the "Zend engine," see http://www.zend.com/) was designed and implemented in a fashion that makes it easy to use as a standalone scripting environment. Therefore, expect to see it available as a standalone scripting engine, much like Perl, in the near future. Moreover, there are talks between the authors of MySQL and Zend about possibly using the scripting engine in MySQL. If this happens, you will then be able to develop MySQL stored procedures in PHP. Thus, one set of familiar syntax can be used to perform the system administration tasks, business logic at the web server level, and the business logic at the database level.

If you keep your eyes on the URLs when navigating the Web, you will notice that next to HTML, the two most widely used extensions are ASP and PHP. ASP is not really a language, but a framework that lets you run your favorite scripting engine under Microsoft's Internet Information Server (IIS). The most widely used option is VBScript. However, you can easily plug in other engines, such as PerlScript. In this context, when I mention ASP I am referring to running a VBScript engine using the ASP framework under IIS. Both VBScript and PHP are powerful scripting languages that contain almost every feature you would need.

The first glaring difference between the two is the syntax of the language. PHP syntax is based on C/C++, Perl, and some UNIX shell scripting. With a UNIX background, you can pick up the PHP syntax in a few minutes. VBScript is modeled after Visual Basic, which means no real object support, no encapsulation, and no inheritance. Also VBScript lacks many system level functions, for example, most file manipulation functionality that is available under PHP has to be executed via invocation of the external File System Object. Being based on Basic, VBScript has some odd features, such as the While/Wend syntax and the lack of short-circuit Boolean evaluation. For example, if you are reading a record set from a database, and you want to test for a value being NULL or an empty string, then code similar to the following should do the trick in most languages:

if isNull(rs(0)) or Cstr(rs(0)) = "" Then

response.write "Empty Value"

end if

but under VBScript, this code will generate a run-time error if the value is NULL upon invocation of the Cstr() function.

You can still develop well-structured code in VBScript, but not real modular code. It is a chore to split your logic into self-contained functions with any level of OO programming.

Aside from VBScript, one major problem with ASP is that it is IIS centric, which takes UNIX-based servers out of the equation. There are a couple of vendors out there trying to develop UNIX flavors of ASP. The problem with this option is that they will always play catch-up, never being able to release all the new functionality that ASP on IIS offers on the same release date.

Also these options rely heavily on Java. If, for example, you check out one of those options — iASP (that is, instant ASP), the first thing you learn is that you need Java to run it. The first example you will likely see is how to instantiate Java Objects from JAR classes. But if my goal is to work in a Java environment, I will not use ASP but rather JSP or Servlets and EJB.

So what gives PHP the edge? For starters it is available on almost any platform and web server. Language syntax is flexible and robust, yet simple. It is a scripted language, which makes the mechanics of development and testing straightforward, resulting in short development times. PHP is available as open source, and you can learn from it and add your changes. That is, by the way, how PHP 3 and now PHP 4 were developed. While PHP is a free open-source environment, you can still take advantage of commercial support from companies such as Zend.

PHP as a scripted language has no strong typing of variables, thus making it easy for beginners to learn. However, PHP does have basic object support, regular expressions, support for recursion, a complete set of string functions, and encryption functions. It can generate images and PDF files on the fly, connect to a multitude of databases, handle many network protocols, and has almost any functionality required in a scripting language for the Web.

A.A.

Terms of Service | Privacy Statement | Copyright © 2024 UBM Tech, All rights reserved.