Tuesday, April 12, 2011

PHP Integration with HTML- Simple Way to integrate PHP with HTML

Chapter 26. Integration with HTML

Topics in This Chapter
·         Sprinkling PHP within an HTML Document
·         Using PHP to Output All HTML
·         Separating HTML from PHP
·         Generating HTML with PHP
By this time, you have learned the basics of PHP. You have a reference for the functions, and you've been introduced to some fundamental problems of programming. But all the examples I've shown have been pieces, snippets for the sake of illustration. This chapter discusses how to integrate PHP into a Web site. It will help you decide whether to build a site completely with PHP, to sprinkle PHP throughout the site, or to simply create a few key PHP-driven pages. It also discusses issues involved in using PHP to generate HTML.


26.1 Sprinkling PHP within an HTML Document
The first and most obvious approach to using PHP is to build HTML files as you have always done, inserting PHP tags as if they were HTML tags. This could take the form of repeating HTML that you replace with a call to a PHP function. It could take the form of a large block of PHP code that generates database output. Or it could be a script that processes a form submission. These are all situations in which the impact of PHP on the site is low. This is a good first step for those new to programming. You are able to insert the smallest amount of PHP code as a test. As your experience and confidence grow, so will your reliance on PHP.
Aside from simple tasks, such as inserting today's data with <?php print(date('Y/m/d')); ?>, you can write your own function for wrapping a block of HTML. Listing 26.1 defines a class for printing HTML tables.
Listing 26.1 Formatting function
<?php
    /*
    ** Simple class for creating HTML tables
    */
    class HTMLTable
    {
        static function start($header=FALSE)
        {
            print("<table border=\"1\">\n");

            if(is_array($header))
            {
                print("<tr>\n");

                foreach($header as $h)
                {
                    print("<th>" .
                       strtoupper($h) .
                       "</th>\n");
                }

                print("</tr>\n");
            }
        }

        static function end()
        {
            print("</table>\n\n");
        }

        static function printRow($label, $field)
        {
            print("<tr>\n");

            //label
            if($label !== "")
            {
                print("<th>" .
                    strtoupper($label) .
                    "</th>\n");
            }
            if(!is_array($field))
            {
                $field = array($field);
            }

            foreach($field as $key=>$value)
            {
                print("<td>");
                if($value === "")
                {
                    print("&nbsp;");
                }
                else
                {
                    print($value);
                }
                print("</td>\n");
            }

            print("</tr>\n");
        }

        static function printSet($set)
        {
            foreach($set as $field)
            {
                if(isset($field['label']))
                {
                    $label = $field['label'];
                    unset($field['label']);
                }
                else
                {
                    $label = "";
                }
                HTMLTable::printRow($label, $field);
            }
        }

    }
?>
<html>
<head>
<title>Listing 26-1</title>
</head>

<body>
<p>
This is an example of using a function to repeat
a commonly-used piece of HTML code.  It builds
out a table, like this one.
</p>
<?php
    //show table with labels on the left
    HTMLTable::start();
    HTMLTable::printRow('step 1', 'Start the table');
    HTMLTable::printRow('step 2', 'Print rows');
    HTMLTable::printRow('step 3', 'End the table');
    HTMLTable::end();
?>
<p>
The HTMLTable class allows you to draw all HTML
tables in the same way.  To change the look of
all tables, you need only edit the class.  Cascading
Style Sheets offer similar technology, but implementing
in PHP means we can make unlimited changes to the
data before building the HTML.  It also means we
can neatly indent the data without affecting the
placement on the final document.
</p>
<?php
    //show a table with labels on top
    HTMLTable::start(array('artist', 'song'));
    HTMLTable::printSet(array(
        array('Thelonious Monk', 'Bemsha Swing'),
        array('John Coltrane', 'Spiral'),
        array('Charlie Parker', 'Koko')
        ));
    HTMLTable::end();
?>
</body>
</html>
One benefit of this technique is that every table renders in exactly the same way. Less text to type for each table means less chance of leaving out part of the formula. This is nice to the programmer, who undoubtedly is eager to find a shortcut to typing long segments of identical HTML. A higher degree of quality is ensured. If a call to the function is mistyped, PHP displays an error. If no errors are displayed, the tables are most likely displayed identically and in the correct format.
If the format of the table needs changing, the code must be altered in only one place. Furthermore, PHP offers the opportunity to make changes to the data before displaying it. In Listing 26.1, the code switches labels to uppercase. Note how the class operates in two modes, labels on top or labels on the left.
Another similar use of PHP is to dress up what is essentially CGI output: a large block of PHP surrounded by HTML so that the output of the code simply appears in a larger page. This is a similar approach offered by SSI (Server-Side Includes). An SSI tag may call a CGI and insert the output in its place.
The approach is appropriate in situations in which your site is mostly static, but certain key areas must be dynamic. The advantage is low impact on the Web server. PHP is used only when absolutely needed. In Listing 26.2 the code generates information that doesn't change, but it's easy to imagine code that pulls stock quotes from a database. It eliminates the need to edit the HTML page each time the information changes, but parts that don't change often, like the layout of the page, are left as static HTML.
Listing 26.2 Dressing up CGI output
<html>
<head>
<title>Listing 26-2</title>
</head>
<body>
<h1>Color Chart</h1>
<p>
The following chart displays the colors
safe for displaying in all browsers.  These
colors should not dither on any computer
with a color palette of at least 256
colors.
</p>
<p>
This chart will only display on browsers
that support table cell background colors.
</p>
<?php
    $color = array("00", "33", "66", "99", "CC", "FF");
    $nColors = count($color);

    for($Red = 0; $Red < $nColors; $Red++)
    {
        print("<table>\n");

        for($Green = 0; $Green < $nColors; $Green++)
        {
            print("<tr>\n");


            for($Blue = 0; $Blue < $nColors; $Blue++)
            {
                $CellColor = $color[$Red] .
                    $color[$Green] . $color[$Blue];

                print("<td bgcolor=\"#$CellColor\">");
                print("<tt>$CellColor</tt>");
                print("</td>\n");
            }

            print("</tr>\n");
        }

        print("</table>\n");
    }
?>
</body>
</html>
While Listing 26.2 is an example of dynamic output, you are often faced with the opposite situation. Your site may be completely static, but you need to accept catalog requests. PHP is a good solution for accepting form submissions. The first step is to create an HTML page that asks for name and address. Listing 26.3 demonstrates.
Listing 26.3 Catalog request form
<html>
<head>
<title>Listing 26-3</title>
</head>
<body>
<p>
Please enter name and address to receive a free catalog.
</p>
<form action="26-4.php">
<table>
<tr>
    <td>Name</td>
    <td><input type="text" name="name"></td>
</tr>
<tr>
    <td>Address</td>
    <td><input type="text" name="address"></td>
</tr>
<tr>
    <td>City</td>
    <td><input type="text" name="city"></td>
</tr>
<tr>
    <td>State</td>
    <td><input type="text" name="state"></td>
</tr>
<tr>
    <td>ZIP</td>
    <td><input type="text" name="zip"></td>
</tr>
<tr>
    <td><input type="reset"></td>
    <td><input type="submit"></td>
</tr>
</table>
</form>
</body>
</html>
The page in Listing 26.3 is a very simple submission form. Each of the input tags will be turned into the _REQUEST array when the submit button is clicked. This calls the script listed in Listing 26.4. The script opens a file named requests.txt for appending and writes each of the form fields into the file. Each field is separated by tab characters, which allows you to import the file into a spreadsheet easily.
Listing 26.4 Form submission
<html>
<head>
<title>Listing 26-4</title>
</head>
<body>
<?
    /*
    ** process form input, append it to file
    */

    $fp = fopen("/tmp/requests.txt", "a");
    if($fp)
    {
        //massage user input
        $_REQUEST['name'] = substr(0, 16, $_REQUEST['name']);
        $_REQUEST['address'] = substr(0, 32, $_REQUEST['address']);
        $_REQUEST['city'] = substr(0, 16, $_REQUEST['city']);
        $_REQUEST['state'] = substr(0, 2, $_REQUEST['state']);
        $_REQUEST['zip'] = substr(0, 10, $_REQUEST['zip']);

        //lock the file
        flock($fp, (LOCK_SH));

        //write request
        fputs($fp, $_REQUEST['name'] . "\t" .
            $_REQUEST['address'] . "\t" .
            $_REQUEST['city'] . "\t" .
            $_REQUEST['state'] . "\t" .
            $_REQUEST['zip'] . "\n");

        //release lock
        flock($fp, LOCK_UN);

        //close the file
        fclose($fp);
    }

?>
<p>
Thank you for your catalog request!
</p>
<p>
<a href="26-3.html">Return to site</a>
</p>
</body>
</html>


26.2 Using PHP to Output All HTML

Any of the examples in the previous section is an excellent first step toward introducing PHP into a Web site. Their impact in terms of server load is relatively low. I like to think of sites using similar approaches as being PHP-enabled, as if they had a small injection of PHP that makes them extraordinary. The step beyond this is what I think of as PHP-powered: a site made completely of PHP. In this approach every byte of output comes from PHP. The print function sends HTML tags. Every page is a script inside a single pair of PHP tags.
You might have noticed that most of the examples in the book take this approach. I have found that while this requires extra time up front, the code is much more maintainable. Once information is put in the context of a PHP variable, it's easy to add something dynamic to it later. It also has the advantage of ultimately being more readable as the page becomes more complex. Compare the simple examples in Listing 26.5 to Listing 26.6. Both change the background color of the page depending on the time of day.
Listing 26.5 Mixing PHP and HTML
<html>
<head>
<title>Listing 26-5</title>
</head>
<?php
    $Hour = date("H");
    $Intensity = round(($Hour/24.0)*(0xFF));
    $PageColor = dechex($Intensity) .
        dechex($Intensity) .
        dechex($Intensity);
?>
<body bgcolor="#<?php print($PageColor); ?>">
<h1>Listing 26-5</h1>
</body>
</html>
Listing 26.6 Converting script to be completely PHP
<?php
    //start document
    print("<html>\n");
    print("<head>\n");
    print("<title>Listing 26-6</title>\n");
    print("</head>\n");
 
    $Hour = date("H");
    $Intensity = round(($Hour/24.0)*(0xFF));
    $PageColor = dechex($Intensity) .
        dechex($Intensity) .
        dechex($Intensity);
    //show body
    print("<body bgcolor=\"#$PageColor\">\n");
    print("<h1>Listing 26-6</h1>\n");
    print("</body>\n");
    print("</html>\n");
?>
My experience has been that having all the HTML inside the PHP script allows very quick changes. I don't have to search for the opening and closing tags buried inside the HTML as in Listing 26.5. It also allows me to break code up into separate lines in the source code that appear as a single line in the output. An example is the header text. I can enhance the readability but not sacrifice the presentation. This has become very handy when dealing with tables. Leaving any whitespace between a td tag and an image causes an extra pixel to appear. In an HTML file, the solution is to run the whole thing together on one line. Inside a PHP script I can have many print calls and send an endline only in the last. The result is a single line in the output, but very readable source code.
The usefulness of these techniques, like that of many others, increases with the size of the project. I've created 50-page Web applications using both approaches and can attest to the value of putting everything inside the PHP code.

 

 

26.3 Separating HTML from PHP

The last approach I want to discuss involves using the include and require functions. As you may recall from Chapter 7, these functions include a file in the PHP code. The file is considered to be a PHP file regardless of the extension on the name. If PHP code appears in the included file, it is surrounded by <?php and ?> tags. You may want to turn back to the functional reference to refresh yourself on the differences between include and require, but they aren't particularly important to this discussion.
Certain chunks of HTML must appear on every well-formed page. Additionally, you may develop repeating elements such as a company logo. Rather than write them into every page, you may choose to put them into a file and dynamically include them. Listing 26.7 contains HTML you might include at the top of every page on a site. In Listing 26.8 are two lines to close a page. Listing 26.10 wraps the content in Listing 26.9 with the opening and closing code to form a complete page.
Listing 26.7 Start of HTML page
<html>
<head>
<title>PHP</title>
</head>
<body>
Listing 26.8 End of HTML page
</body>
</html>
Listing 26.9 Page content
<p>
This is the body of the page.
It's just a bit of HTML.
</p>
Listing 26.10 Page-building script
<?php
    // include code to open HTML page
    require("26-7");
 
    // include content
    require("26-9");
 
    // include code to close HTML page
    require("26-8");
?>
In this way, HTML and PHP are separated into modules. In this example, I have hardcoded the inclusion of a two-line HTML file, but I could just as easily have included the color tables from Listing 26.2. The HTML in Listing 26.7 can be reused from page to page, and if I need to add something to every page on the site, I need to edit only that one file. I might want to add the PHP function from Listing 26.1. It will then be available for use inside the code from Listing 26.9.
It may occur to you that this approach is exhibiting another pattern. Every page on the site will simply become three calls to require. The first and last calls will always be the same. In fact, every page on the site will vary simply by the name of the file included in the second require statement. This takes us beyond the issue of integrating HTML and PHP and into the structural design of a site. It is possible to create a site that has exactly one PHP script. This idea is developed in Chapter 27.

26.4 Generating HTML with PHP
An HTML select tag allows you to list several options that appear as a pull-down menu. I am often in the situation of creating the contents of the list on the fly. Sometimes the contents are pulled from a database, such as for choosing from among users in a Web application. Other times the contents are generated, such as choosing month, day, and year. There are two aspects to this problem. First, there is the fairly simple problem of creating all the values for the option tags. This is best accomplished in a loop. The second issue deals with preselecting one of the options.
Regardless of the source of the contents, database or otherwise, the technique is similar. To illustrate, I'll develop a function for generating three select fields for getting a date from the user: month, day, and year. To generate a list of the months, it is best to draw from an array to display their names. Days and years are numbers, so their values and displayed names are the same. Listing 26.11 demonstrates.
Listing 26.11 Date selector
<?php
    /*
    ** Get three selectors for month, day, year
    */
    function getDateSelectors($name, $date=NULL)
    {
        static $monthName = array(1=>"January",
        "February", "March", "April", "May",
        "June", "July", "August", "September",
        "October", "November", "December");

        if($date === NULL)
        {
            $date = time();
        }


        //make Month selector
        $givenMonth = date("m", $date);
        $fields = "<select name=\"{$name}[month]\">\n";
        for($m = 1; $m <= 12; $m++)
        {
            $fields .= "<option value=\"$m\"";
            if($m == $givenMonth)
            {
                $fields .= " selected";
            }
            $fields .= ">" . $monthName[$m] . "</option>\n";
        }
        $fields .= "</select>\n";

        $fields .= "<select name=\"{$name}[day]\">\n";
        $givenDay = date("d", $date);
        for($d=1; $d <= 31; $d++)
        {
            $fields .= "<option value=\"$d\"";
            if($d == $givenDay)
            {
                $fields .= " selected";
            }
            $fields .= ">$d</option>\n";
        }
        $fields .= "</select>\n";

        $fields .= "<select name=\"{$name}[year]\">\n";
        $givenYear = date("Y", $date);
        $lastYear = date('Y')+5;
        for($y = date('Y')-5; $y <= $lastYear; $y++)
        {
            $fields .= "<option value=\"$y\"";
            if($y == $givenYear)
            {
                $fields .= " selected";
            }
            $fields .= ">$y</option>\n";
        }
        $fields .= "</select>\n";

        return($fields);
    }


    //start document
    print("<html>\n" .
        "<head>\n" .
        "<title>Listing 26-11</title>\n" .
        "</head>\n");

    //start body
    print("<body>\n");


    //choose default date
    if(isset($_REQUEST['sample']))
    {
        //construct time
        $UseDate = mktime(0, 0, 0,
            $_REQUEST['sample']['month'],
            $_REQUEST['sample']['day'],
            $_REQUEST['sample']['year']);
    }
    else
    {
        //use default
        $UseDate = NULL;
    }

    //make simple form
    print("<form action=\"{$_SERVER['PHP_SELF']}\">\n");
    print(getDateSelectors("sample", $UseDate));
    print("<input type=\"submit\">\n");
    print("</form>\n");

    //close HTML document
    print("</body>\n" .
        "</html>\n");
?>
The options for each selector are generated in a for loop. Months range from 1 to 12, days from 1 to 31. For years, I've chosen to present an 11-year range around the current year. Notice that if you submit a date, it refreshes the page and sets the form with the date you chose. The key is the addition of the if statement. Each time through the loop, the current value is tested against the one to be selected.
Note how the three selectors pass their values as part of an array. PHP understands to create array elements from form fields named with square brackets. If you duplicate this technique, do not include quotes around the associative key. That is, use {$name}[month] instead of {$name}['month']. When parsing form fields, PHP does not expect string delimiters around the key.

By PHP with No comments

0 comments:

Post a Comment

    • Popular
    • Categories
    • Archives