DekGenius.com
Previous Section  < Day Day Up >  Next Section

C.9 Chapter 10

C.9.1 Exercise 1:

Here's a sample template file, article.html:

<html>
<head><title>{title}</title></head>
<body>
<h1>{headline}</h1>
<h2>By {byline}</h2>
{article}
<hr/>
<h4>Page generated: {date}</h4>
</body>
</html>

Here's the program that replaces the template fields with actual values. It stores the field names and values in an array and then uses foreach( ) to iterate through that array and do the replacement:

<?php
$page = file_get_contents('article.html');
if ($page =  =  = false) {
    die("Can't read article.html: $php_errormsg");
}
$vars = array('{title}' => 'Man Bites Dog',
              '{headline}' => 'Man and Dog Trapped in Biting Fiasco',
              '{byline}' => 'Ireneo Funes',
              '{article}' => "<p>While walking in the park today,
Bioy Casares took a big juicy bite out of his dog, Santa's Little
Helper. When asked why he did it, he said, \"I was hungry.\"</p>",
              '{date}' => date('l, F j, Y'));
foreach ($vars as $field => $new_value) {
    $page = str_replace($field, $new_value, $page);
}
$result = file_put_contents('dog-article.html', $page);
if (($result =  =  = false) || ($result =  = -1)) {
    die("Couldn't write dog-article.html: $php_errormsg");
}
?>

C.9.2 Exercise 2:

Here's a sample addresses.txt:

brilling@tweedledee.example.com
slithy@unicorn.example.com
uffish@knight.example.net
slithy@unicorn.example.com
jubjub@sheep.example.com
tumtum@queen.example.org
slithy@unicorn.example.com
uffish@knight.example.net
manxome@king.example.net
beamish@lion.example.org
uffish@knight.example.net
frumious@tweedledum.example.com
tulgey@carpenter.example.com
vorpal@crow.example.org
beamish@lion.example.org
mimsy@walrus.example.com
frumious@tweedledum.example.com
raths@owl.example.net
frumious@tweedledum.example.com

Here's the program to count the addresses:

<?php
$in_fh = fopen('addresses.txt','rb');
if (! $in_fh) {
    die("Can't open addresses.txt: $php_errormsg");
}
// We'll count addresses with this array
$addresses = array( );
for ($line = fgets($in_fh); ! feof($in_fh); $line = fgets($in_fh)) {
    if ($line =  =  = false) {
        die("Error reading line: $php_errormsg");
    } else {
        $line = trim($line);
        // Use the address as the key in $addresses
        // the value is the number of times that the
        // address has appeared
        $addresses[$line] = $addresses[$line] + 1;
    }
}
if (! fclose($in_fh)) {
    die("Can't close addresses.txt: $php_errormsg");
}
$out_fh = fopen('addresses-count.txt','wb');
if (! $out_fh) {
    die("Can't open addresses-count.txt: $php_errormsg");
}
// Reverse sort $addresses by element value
arsort($addresses);
foreach ($addresses as $address => $count) {
    // Don't forget the newline!
    if (fwrite($out_fh, "$count,$address\n") =  =  = false) {
        die("Can't write $count,$address: $php_errormsg");
    }
}
if (! fclose($out_fh)) {
    die("Can't close addresses-count.txt: $php_errormsg");
}
?>

C.9.3 Exercise 3:

<?php
$fh = fopen('csvdata.csv', 'rb');
if (! $fh) {
    die("Can't open csvdata.csv: $php_errormsg");
}
print "<table>\n";
       
for ($line = fgetcsv($fh, 1024); ! feof($fh); $line = fgetcsv($fh, 1024)) {
    // Use implode as in Example 4.21
    print '<tr><td>' . implode('</td><td>', $line) . "</td></tr>\n";
}
print '</table>';
?>

C.9.4 Exercise 4:

<?php
  // Load the form element helper functions
require 'formhelpers.php';
if ($_POST['_submit_check']) {
    // If validate_form( ) returns errors, pass them to show_form( )
    if ($form_errors = validate_form( )) {
        show_form($form_errors);
    } else {
        // The submitted data is valid, so process it
        process_form( );
    }
} else {
    // The form wasn't submitted, so display
    show_form( );
}
function show_form($errors = '') {
    if ($errors) {
        print 'You need to correct the following errors: <ul><li>';
        print implode('</li><li>',$errors);
        print '</li></ul>';
    }
    // the beginning of the form
    print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
    // the file name
    print' File name: ';
    input_text('filename', $_POST);
    print '<br/>';
    // the submit button
    input_submit('submit','Show File');
    // the hidden _submit_check variable
    print '<input type="hidden" name="_submit_check" value="1"/>';
    // the end of the form
    print '</form>';
}
function validate_form( ) {
    $errors = array( );
    // filename is required
    if (! strlen(trim($_POST['filename']))) {
        $errors[  ] = 'Please enter a file name.';
    } else {
        // build the full file name from the web server document root
        // directory, a slash, and the submitted value
        $filename = $_SERVER['DOCUMENT_ROOT'] . '/' . $_POST['filename'];
        
        // Use realpath to resolve any .. sequences
        $filename = realpath($filename);
        
        // make sure $filename begins with the document root directory
        $docroot_len = strlen($_SERVER['DOCUMENT_ROOT']);
        if (substr($filename, 0, $docroot_len) != $_SERVER['DOCUMENT_ROOT']) {
            $errors[  ] = 'File name must be under the document root directory.';
        }
    }
    return $errors;
}
function process_form( ) {
    // reconstitute the full file name, as in validate_form( )
    $filename = $_SERVER['DOCUMENT_ROOT'] . '/' . $_POST['filename'];
    $filename = realpath($filename);
    // print the contents of the file
    print file_get_contents($filename);
}
?>

C.9.5 Exercise 5:

The new validate_form( ) function that implements the additional rule:

function validate_form( ) {
    $errors = array( );
    // filename is required
    if (! strlen(trim($_POST['filename']))) {
        $errors[  ] = 'Please enter a file name.';
    } else {
        // build the full file name from the web server document root
        // directory, a slash, and the submitted value
        $filename = $_SERVER['DOCUMENT_ROOT'] . '/' . $_POST['filename'];
        
        // Use realpath to resolve any .. sequences
        $filename = realpath($filename);
        
        // make sure $filename begins with the document root directory
        $docroot_len = strlen($_SERVER['DOCUMENT_ROOT']);
        if (substr($filename, 0, $docroot_len) != $_SERVER['DOCUMENT_ROOT']) {
            $errors[  ] = 'File name must be under the document root directory.';
        } elseif (strcasecmp(substr($filename, -5), '.html') != 0) {
            $errors[  ] = 'File name must end in .html';
        }
    }
    return $errors;
}

    Previous Section  < Day Day Up >  Next Section