100% found this document useful (4 votes)
37 views

Instant Access to PHP 5 Advanced Visual QuickPro Guide 2nd Edition Larry Ullman ebook Full Chapters

QuickPro

Uploaded by

vlorlokwai
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (4 votes)
37 views

Instant Access to PHP 5 Advanced Visual QuickPro Guide 2nd Edition Larry Ullman ebook Full Chapters

QuickPro

Uploaded by

vlorlokwai
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 81

Visit https://ebookgate.

com to download the full version and


explore more ebooks

PHP 5 Advanced Visual QuickPro Guide 2nd Edition


Larry Ullman

_____ Click the link below to download _____


https://ebookgate.com/product/php-5-advanced-visual-
quickpro-guide-2nd-edition-larry-ullman/

Explore and download more ebooks at ebookgate.com


Here are some recommended products that might interest you.
You can download now and explore!

PHP for the Web Visual QuickStart Guide 4th Edition Larry
Ullman

https://ebookgate.com/product/php-for-the-web-visual-quickstart-
guide-4th-edition-larry-ullman/

ebookgate.com

Visual Spatial Thinking for Advanced Learners Grades 3 5


1st Edition Emily Hollett

https://ebookgate.com/product/visual-spatial-thinking-for-advanced-
learners-grades-3-5-1st-edition-emily-hollett/

ebookgate.com

Zend PHP 5 Certification Study Guide Third Edition Davey


Shafik With Ben Ramsey

https://ebookgate.com/product/zend-php-5-certification-study-guide-
third-edition-davey-shafik-with-ben-ramsey/

ebookgate.com

PHP 5 Power Programming 1st Edition Andi Gutmans

https://ebookgate.com/product/php-5-power-programming-1st-edition-
andi-gutmans/

ebookgate.com
Magento PHP Developer s Guide 2nd Edition Allan Macgregor

https://ebookgate.com/product/magento-php-developer-s-guide-2nd-
edition-allan-macgregor/

ebookgate.com

PHP Mysql For Advanced Learning 3rd Edition Hirdesh


Bhardwaj

https://ebookgate.com/product/php-mysql-for-advanced-learning-3rd-
edition-hirdesh-bhardwaj/

ebookgate.com

Advanced Visual Basic 2010 5th Edition Kip R. Irvine

https://ebookgate.com/product/advanced-visual-basic-2010-5th-edition-
kip-r-irvine/

ebookgate.com

Beginning PHP and MySQL 5 From Novice to Professional


Second Edition W. Jason Gilmore

https://ebookgate.com/product/beginning-php-and-mysql-5-from-novice-
to-professional-second-edition-w-jason-gilmore/

ebookgate.com

Beginning PHP 5 and MySQL From Novice to Professional 1st


Edition W Jason Gilmore

https://ebookgate.com/product/beginning-php-5-and-mysql-from-novice-
to-professional-1st-edition-w-jason-gilmore/

ebookgate.com
VISUAL QUICKPRO GUIDE

PHP 5 ADVANCED
Larry Ullman

Peachpit Press
Visual QuickPro Guide
PHP 5 Advanced
Larry Ullman

Peachpit Press
1249 Eighth Street
Berkeley, CA 94710
510/524-2178
510/524-2221 (fax)

Find us on the Web at: www.peachpit.com


To report errors, please send a note to: [email protected]
Peachpit Press is a division of Pearson Education.
Copyright © 2007 by Larry Ullman

Editor: Rebecca Gulick


Copy Editor: Robert Campbell
Technical Reviewer: Jay Blanchard
Proofreader: Liz Welch
Production Coordinator: Becky Winter
Compositor: Kate Kaminski
Indexer: Karin Arrigoni
Cover Design: Peachpit Press

Notice of Rights
All rights reserved. No part of this book may be reproduced or transmitted in any form by any
means, electronic, mechanical, photocopying, recording, or otherwise, without the prior written
permission of the publisher. For information on getting permission for reprints and excerpts,
contact [email protected].

Notice of Liability
The information in this book is distributed on an “As Is” basis, without warranty. While every
precaution has been taken in the preparation of the book, neither the author nor Peachpit Press
shall have any liability to any person or entity with respect to any loss or damage caused or
alleged to be caused directly or indirectly by the instructions contained in this book or by the
computer software and hardware products described in it.

Trademarks
Visual QuickPro Guide is a registered trademark of Peachpit Press, a division of Pearson
Education.

MySQL is a registered trademark of MySQL AB in the United States and in other countries.
Macintosh and Mac OS X are registered trademarks of Apple Inc. Microsoft, Windows, Windows
XP, and Windows Vista are registered trademarks of Microsoft Corp. Screenshots of Web sites in
this book are copyrighted by the original holders.

Many of the designations used by manufacturers and sellers to distinguish their products are
claimed as trademarks. Where those designations appear in this book, and Peachpit was aware
of a trademark claim, the designations appear as requested by the owner of the trademark. All
other product names and services identified throughout this book are used in editorial fashion
only and for the benefit of such companies with no intention of infringement of the trademark.
No such use, or the use of any trade name, is intended to convey endorsement or other affilia-
tion with this book.

ISBN-13: 978-0-321-37601-5 ISBN-10: 0-321-37601-3

987654321

Printed and bound in the United States of America


Dedication
To my good friend Michael K. and his family:
I cannot thank you all enough for your con-
tinuing friendship, generosity, and kindness
over these many years.
My utmost thanks to…
Jessica, the love of my life, for just about
everything.
Zoe and Sam, for making my world a
better place.
The grandparents, who traveled far and
often, pitching in with babysitting and
housework so that I might write this book.
Everyone at Peachpit Press for their support,
for their dedication to putting out quality
books, and for everything else they do to
make all this happen.
The most excellent editor, Rebecca Gulick,
for so many reasons.
Bob Campbell, for his spot-on copy editing
and attention to detail.
The production coordinator, Becky Winter,
the compositor, Kate Kaminski, the proof-
reader, Liz Welch, and the indexer, Karin
Arrigoni, who turn my mess of files into an
actual book.
Jay Blanchard, for his technical review.
The readers, the readers, the readers!
Contents at a Glance

Introduction ix
Chapter 1: Advanced PHP Techniques 1
Chapter 2: Developing Web Applications 43
Chapter 3: Advanced Database Concepts 81

Contents at a Glance
Chapter 4: Security Techniques 123
Chapter 5: E-commerce Techniques 169
Chapter 6: Basic Object-Oriented
Programming 233
Chapter 7: Advanced OOP 263
Chapter 8: Real-World OOP 309
Chapter 9: Networking with PHP 347
Chapter 10: PHP and the Server 373
Chapter 11: PHP’s Command-Line Interface 417
Chapter 12: Using PEAR 443
Chapter 13: Ajax 481
Chapter 14: XML and PHP 529
Index 569

v
Table of Contents
Introduction ix
Chapter 1: Advanced PHP Techniques 1
Multidimensional Arrays . . . . . . . . . . . . . . . . . . . . . . 2
Advanced Function Definitions . . . . . . . . . . . . . . . 18
The Heredoc Syntax . . . . . . . . . . . . . . . . . . . . . . . . . 31
Using printf() and sprintf() . . . . . . . . . . . . . . . . . . . 37
Table of Contents

Chapter 2: Developing Web Applications 43


Documenting Code . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Code Style and Structure . . . . . . . . . . . . . . . . . . . . . 47
Modularizing a Web Site . . . . . . . . . . . . . . . . . . . . . 49
Affecting the Browser Cache . . . . . . . . . . . . . . . . . . 74

Chapter 3: Advanced Database Concepts 81


Storing Sessions in a Database . . . . . . . . . . . . . . . . 82
Working with U.S. Zip Codes . . . . . . . . . . . . . . . . . 96
Creating Stored Functions . . . . . . . . . . . . . . . . . . . 110
Displaying Results Horizontally . . . . . . . . . . . . . . 116

Chapter 4: Security Techniques 123


Remembering the Basics . . . . . . . . . . . . . . . . . . . . 124
Validating Form Data . . . . . . . . . . . . . . . . . . . . . . . 126
Using PECL Filter . . . . . . . . . . . . . . . . . . . . . . . . . . 136
Authentication with PEAR Auth . . . . . . . . . . . . . 143
Using MCrypt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157

Chapter 5: E-commerce Techniques 169


E-commerce Concepts . . . . . . . . . . . . . . . . . . . . . . 170
Creating the Database . . . . . . . . . . . . . . . . . . . . . . 171
Creating the Configuration File . . . . . . . . . . . . . . 183
Making the Template . . . . . . . . . . . . . . . . . . . . . . . 190
Creating the Index Page . . . . . . . . . . . . . . . . . . . . . 197

vi
Table of Contents

Browsing by Category . . . . . . . . . . . . . . . . . . . . . . . 199


Showing a Product . . . . . . . . . . . . . . . . . . . . . . . . . 205
Implementing a Shopping Cart . . . . . . . . . . . . . . 212
Validating Credit Cards . . . . . . . . . . . . . . . . . . . . . 224

Chapter 6: Basic Object-Oriented


Programming 233
OOP Theory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
Defining a Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
Creating an Object . . . . . . . . . . . . . . . . . . . . . . . . . 240
The $this Attribute . . . . . . . . . . . . . . . . . . . . . . . . . 244
Creating Constructors . . . . . . . . . . . . . . . . . . . . . . 251
Creating Destructors . . . . . . . . . . . . . . . . . . . . . . . 256
Autoloading Classes . . . . . . . . . . . . . . . . . . . . . . . . 260

Chapter 7: Advanced OOP 263

Table of Contents
Advanced Theories . . . . . . . . . . . . . . . . . . . . . . . . . 264
Inheriting Classes . . . . . . . . . . . . . . . . . . . . . . . . . . 266
Inheriting Constructors and Destructors . . . . . 271
Overriding Methods . . . . . . . . . . . . . . . . . . . . . . . . 276
Access Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
Using the Scope Resolution Operator . . . . . . . . . 289
Creating Static Members . . . . . . . . . . . . . . . . . . . . 294
Abstract Classes and Methods . . . . . . . . . . . . . . . 300

Chapter 8: Real-World OOP 309


Catching Exceptions . . . . . . . . . . . . . . . . . . . . . . . . 310
Extending the Exception Class . . . . . . . . . . . . . . 317
Creating a Shopping Cart Class . . . . . . . . . . . . . . 328
Using the Cart Class . . . . . . . . . . . . . . . . . . . . . . . . 340

Chapter 9: Networking with PHP 347


Accessing Other Web Sites . . . . . . . . . . . . . . . . . . 348
Working with Sockets . . . . . . . . . . . . . . . . . . . . . . 355
Performing IP Geolocation . . . . . . . . . . . . . . . . . . 363
Using cURL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368

Chapter 10: PHP and the Server 373


Compressing Files . . . . . . . . . . . . . . . . . . . . . . . . . . 374
PHP-GTK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385
Establishing a cron . . . . . . . . . . . . . . . . . . . . . . . . . 399
Scheduling Tasks on Windows . . . . . . . . . . . . . . . 402
Using COM with PHP . . . . . . . . . . . . . . . . . . . . . . . 404

vii
Table of Contents

Chapter 11: PHP’s Command-Line Interface 417


Testing Your Installation . . . . . . . . . . . . . . . . . . . . 418
Executing Bits of Code . . . . . . . . . . . . . . . . . . . . . . 422
Creating a Command-Line Script . . . . . . . . . . . . 424
Running a Command-Line Script . . . . . . . . . . . . 428
Working with Command-Line Arguments . . . . 432
Taking Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437

Chapter 12: Using PEAR 443


Using Benchmark . . . . . . . . . . . . . . . . . . . . . . . . . . 444
Using HTML_QuickForm . . . . . . . . . . . . . . . . . . . 456
Using Mail_Mime . . . . . . . . . . . . . . . . . . . . . . . . . . 469

Chapter 13: Ajax 481


Introduction to Ajax . . . . . . . . . . . . . . . . . . . . . . . . 482
A Simple Example . . . . . . . . . . . . . . . . . . . . . . . . . . 484
Table of Contents

Full-Fledged Ajax . . . . . . . . . . . . . . . . . . . . . . . . . . . 506


Debugging Ajax Applications . . . . . . . . . . . . . . . . 523

Chapter 14: XML and PHP 529


What Is XML? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 530
XML Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 532
Attributes, Empty Elements, and Entities . . . . . 536
Document Type Definitions . . . . . . . . . . . . . . . . . 540
Parsing XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 548
Creating an RSS Feed . . . . . . . . . . . . . . . . . . . . . . . 562

Index 569

viii
Introduction
i
If you’re looking at this book, then I probably don’t need to tell you how great PHP is.
Presumably, since you’re perusing the pages of an advanced text on the topic, you are
already using PHP for developing dynamic Web sites. Maybe you’ve been doing so for
a couple of years, perhaps just a couple of months. You could have learned PHP on your
own, in a class, or by reading one of the many excellent books on the subject. (I’m
referring not just to my own, of course!) Whatever the case, with some experience

Introduction
under your belt, you probably don’t want another “here’s how to use PHP and isn’t it
swell” book. What you probably want to learn is how to use PHP more efficiently, more
securely, faster, and all-around better than you already are. If so, you’ve found the
right book.
In this humble author’s (or not-so-humble author’s) opinion, advanced PHP is about
learning: how to do different things, how to improve upon the basic things, and about
technologies that intersect with PHP. In short, you know how to make a dynamic Web
site with PHP, but you’d like to know how to make a better Web site, with every possible
meaning of “better.” That’s the approach I’ve taken in writing this book. I’ve not set
out to blow your mind discussing esoteric idiosyncrasies the language has, rewriting
the PHP, MySQL, or Apache source code, or making theoretically interesting but
practically useless code. In short, I present to you several hundred pages of beyond-the-
norm but still absolutely necessary (and often cool) tips and techniques.

ix
Introduction

About This Book


Simply put, I’ve tried to make this book’s
content accessible and useful for every
PHP programmer out there. As I suggest
in the introductory paragraphs, I believe
that “advanced” PHP is mostly a matter
of extended topics. You already possess
all the basic knowledge—you retrieve data-
base query results in your sleep—but want
to go further. This may mean learning object-
oriented programming (OOP), using PEAR
(PHP Extension and Application Repository),
incorporating Ajax (Asynchronous JavaScript
and XML) into a site, or improving upon
aspects of your existing skill set.
My definition of advanced PHP program-
ming covers three loosely grouped skills:
◆ Doing what you already do better, faster,
Introduction

and more securely


◆ Learning more sophisticated PHP tech-
niques
◆ Doing standard things using PHP and
other technologies (like PEAR, Ajax,
or OOP)
This book can be divided into three sections,
corresponding to those skills. The first five
chapters cover advanced PHP knowledge
in general: programming techniques, Web
applications, databases, security, and e-com-
merce. They all cover information that the
average PHP programmer may not be famil-
iar with but should be able to comprehend,
providing useful code in the process.
The next six chapters focus on extending
your knowledge to areas of PHP with which
you might not be as familiar. Half of this sec-
tion goes over object-oriented programming
in great detail, from the fundamentals to
advanced topics to some real-world examples.
The other three chapters are on different ways
you might use PHP: to communicate with

x
Introduction

networked servers, to communicate with


the host server, or from a command-line
interface. The remaining three chapters each
deal with a specific technology tied into
PHP: PEAR, Ajax, and XML.
Two bonus chapters, “Image Generation” and
“Creating PDFs”, can be downloaded from
Peachpit’s Web site. Those two chapters,
which are available for free, provide another
100 pages of content showing how PHP ties
into related, and very useful, technologies.
Visit www.peachpit.com/title/0321376013
to learn how to register this book and
download the chapters.
Most examples used in this book are intended
to be applicable in the real world, omitting
the frivolous code you might see in other
books, tutorials, and manuals. I focus as much
on the philosophies involved as on the coding

Introduction
itself so that, in the end, you will come away
with not just how to do this or that but also
how to apply the overarching mentality to
your own, individual projects.
Unlike with most of my other books, I do
not expect that you’ll necessarily read this
book in sequential order, for the most part.
Some chapters do assume that you’ve read
others, like the object-oriented ones, which
have a progression to them. Some later
chapters also reference examples completed
in earlier ones. If you read the later ones
first, you’ll just need to quickly hop over to
the earlier ones to generate whatever data-
base or scripts the later chapter requires.
Finally, I’ll be using XHTML in my scripts
instead of HTML. I’ll also use some CSS, as
warranted. I do not discuss either of these
subjects in this book (and, to be frank, may
not adhere to them perfectly). If you are not
already familiar with the subjects, you should
look at some online resources or good books
(such as Elizabeth Castro’s excellent Visual
QuickStart Guides) for more information.

xi
Introduction

What’s new in this edition


The most important change in this edition
of the book is that every bit of code has been
updated, rewritten, or replaced to ensure
100 percent compatibility with PHP 5. Many
of the examples have also been modified
to take advantage of features added to the
language.
What is also new is my approach. The first
edition of this text was the second book I
ever wrote. I’ve learned a lot since then, both
in terms of PHP and in terms of what read-
ers expect in a book. A lot of my valuable
experience in this latter category comes
from the constant interactions with other
readers through email and my supporting
forums (www.DMCInsights.com/phorum/). A
fair amount of material is therefore based
upon frequently asked questions I see.
Introduction

How this book compares to my


others
Those readers who have come to this book
from my PHP for the World Wide Web: Visual
QuickStart Guide may find themselves in a
bit over their heads. This book does assume
comfort with standard PHP programming,
in particular debugging your own scripts.
I’m not suggesting you put this book down,
but if you find it goes too fast for you, or
assumes knowledge you don’t currently pos-
sess, you may want to check out my PHP
and MySQL for Dynamic Web Sites: Visual
QuickPro Guide instead.
If you have read the PHP and MySQL book,
or the first edition of this one, I’m hoping
that you’ll find this to be a wonderful addi-
tion to your library and skill set.

xii
Introduction

About PHP 5
Although version 5 of PHP has been out
since July 2004 (when the first non-beta
version was released), there are still a large
number of servers running older versions
of PHP, particularly outside of the United
States. This book does assume you’re using
PHP 5, although some examples will work
with older versions of the language.
The most important change in PHP 5,
with respect to this book, is the completely
different object model and syntax. Object-
oriented programming in PHP 4 is a rather
watered-down concept, really not worth
using in comparison to PHP 5’s OOP. The
object-oriented chapters use PHP 5 syntax
exclusively, and that code will not work on
older versions of the language.

Introduction
In addition, PHP 5 added support for the
Improved MySQL extension, designed for
use with MySQL 4.1 or later. With only one
or two exceptions, I use these Improved
MySQL functions instead of the older, “regu-
lar” MySQL functions. If your PHP installa-
tion (or MySQL installation) does not sup-
port these functions, you’ll need to change
the code accordingly.

xiii
Introduction

What You’ll Need


Just as this book assumes that you already
possess the fundamental skills to program in
PHP (and, more important, to debug it when
things go awry), it also assumes that you
already have everything you need to follow
along with the material. For starters, this
means a PHP-enabled server. At the time of
this writing, the latest version of PHP was
5.2, and much of the book depends upon
your using at least PHP 5.0.
Along with PHP, you’ll often need a database
application. I use MySQL for the examples,
but you can use anything. And, for the scripts
in some of the chapters to work—particularly
the last five—your PHP installation will have
to include support for the corresponding
technology, and that technology’s library
Introduction

may need to be installed, too. Fortunately


PHP 5 comes with built-in support for many
advanced features. If the scripts in a par-
ticular chapter require special extensions,
that will be referenced in the chapter’s intro-
duction. This includes the few times where
I make use of a PEAR or PECL class. Nowhere
in this book will I discuss installation, though,
as I expect you should already know or have
accomplished that.
As with any issue, should you have questions
or problems, you can always search the Web
or post a message in my support forums for
assistance.
Beyond PHP, you need the things you should
already have: a text editor or IDE, an FTP
application (if using a remote server), and a
Web browser. All of the code in this book
has been tested on both Windows XP and
Mac OS X; you’ll see screen shots in both
operating systems.

xiv
Introduction

Support Web Site


I have developed a Web site to support this
book, available at www.DMCinsights.com/
phpvqp2/. This site:

◆ Has every script available for download


◆ Has the SQL commands available for
download
◆ Has extra files, as necessary, available
for download
◆ Lists errors that have been found in
the book
◆ Has a support forum where you can get
help or assist others
◆ Provides a way to contact me directly
When using this site, please make sure

Introduction
you’ve gone to the correct URL (the book’s
title and edition are plastered everywhere).
Each book I’ve written has its own support
area; if you go to the wrong one, the down-
loadable files won’t match those in the book.
Two bonus chapters, “Image Generation”
and “Creating PDFs,” can be downloaded
for free. Visit www.peachpit.com/title/
0321376013 to learn how to register this
book and access the chapters.

xv
This page intentionally left blank
Advanced
PHP Techniques
1
At the most basic level good programming is determined by whether or not an appli-
cation or script works as intended. This is where the beginning programmer will leave
things, and there is nothing wrong with that. However, the advanced programmer
will work past that point, striving toward improved efficiency, reliability, security,
and portability. This book teaches you how to develop the skills of an advanced PHP
programmer.

Advanced PHP techniques


One thing the advanced PHP programmer does better than the beginner is learning to
take advantage of more obscure or harder-to-comprehend features of the language. For
example, while you probably already know how to use arrays, you may not have mas-
tered multidimensional arrays: creating them, sorting them, and so on. You have writ-
ten your own functions by this point but may not understand how to use recursion and
static variables. Issues like these will be discussed as well as other beyond-the-basics
concepts, like the heredoc syntax and the printf()/sprintf() family of functions.

1
Chapter 1

Multidimensional Arrays
Because of their power and flexibility, arrays
are widely used in all PHP programming. For
advanced uses, the multidimensional array
often solves problems where other variable
types just won’t do.
For the first of the two examples, I’ll demon-
strate how to sort a multidimensional array.
It’s a common question users have and isn’t
as hard as one might think. For the second
example, I’ll create a database-driven to-do Figure 1.1 One use of multidimensional
list, which can have limitless dimensions arrays will be to create a nested to-do
list.
(Figure 1.1).

Sorting multidimensional arrays


Sorting arrays is easy using PHP, thanks to
the sort(), ksort(), and related functions.
You can sort a one-dimensional array by key,
Multidimensional Arrays

by value, in reverse order, etc. But these func-


tions will not work on multidimensional
arrays (not as you’d probably like, at least).
Say you have an array defined like so:
$a = array (
array (‘key1’ => 940, ‘key2’ => ‘blah’),
array (‘key1’ => 23, ‘key2’ => ‘this’),
array (‘key1’ => 894, ‘key2’ => ‘that’)
);
Figure 1.2 The multidimensional array
This is a simple two-dimensional array (an sorted by numeric value (key1).
array whose elements are also arrays) that
you might need to sort using key1 (a numeric
sort) or key2 (an alphabetical sort). To sort a
multidimensional array, you define your own
sort function and then tell PHP to use that
function via the usort(), uasort(), or
uksort() function. The function you define
must take exactly two arguments and return
a value indicating which should come first.

2
Advanced PHP Techniques

To sort the preceding array on the first key,


the sorting function would like this:
function mysort1 ($x, $y) {
return ($x[‘key1’] > $y[‘key1’]);
}

Then the PHP code would use this function


by doing:
usort ($a, ‘mysort1’);

Figure 1.2 shows the same array at this


point.
PHP will continue sending the inner arrays
to this function so that they may be sorted. If
you want to see this in detail, print the values
being compared in the function (Figure 1.3).
The usort() function sorts by values and does
not maintain the keys (for the outermost
Figure 1.3 By printing out the values array). If you used uasort(), the keys would
of $x[‘key1’] and $y[‘key1’], one be maintained, and if you used uksort(), the

Multidimensional Arrays
can see how the user-defined sorting sort would be based upon the keys.
function is invoked.
To sort on the second key in the preceding
example, you would want to compare two
strings. That code would be (Figure 1.4
shows the result):
function mysort2 ($x, $y) {
return strcasecmp($x[‘key2’],
➝ $y[‘key2’]);
}
usort ($a, ‘mysort2’);

Or you could just use strcmp(), to perform a


case-sensitive sort.
To see this in action for yourself, let’s run
through an example.

Figure 1.4 An alphabetical sort on


the example array using key2.

3
Chapter 1

To sort a multidimensional array:


1. Create a new PHP script in your text edi-
tor or IDE, starting with the HTML code
(Script 1.1).
<!DOCTYPE html PUBLIC “-//W3C//
➝ DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/
➝ xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/
➝ xhtml” xml:lang=”en” lang=”en”>
<head>
<meta http-equiv=”content-type”
➝ content=”text/html; charset=
➝ iso-8859-1” />
<title>Sorting Multidimensional
➝ Arrays</title>
</head>
<body>
Multidimensional Arrays

<?php # Script 1.1 - sort.php

2. Define a multidimensional array.


$students = array (
256 => array (‘name’ => ‘Jon’,
➝ ‘grade’ => 98.5),
2 => array (‘name’ => ‘Vance’,
➝ ‘grade’ => 85.1),
9 => array (‘name’ => ‘Stephen’,
➝ ‘grade’ => 94.0),
364 => array (‘name’ => ‘Steve’,
➝ ‘grade’ => 85.1),
68 => array (‘name’ => ‘Rob’,
➝ ‘grade’ => 74.6)
);
The outer array, $students, has five ele-
ments, each of which is also an array. The
inner arrays use the student’s ID for the
key (a made-up value) and store two
pieces of data: the student’s name and
their grade.
continues on page 6

4
Advanced PHP Techniques

Script 1.1 This script defines a two-dimensional array, which is then sorted based upon the inner array values.

1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"


2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4 <head>
5 <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
6 <title>Sorting Multidimensional Arrays</title>
7 </head>
8 <body>
9 <?php # Script 1.1 - sort.php
10
11 /* This page creates a multidimensional array
12 * of names and grades.
13 * The array is then sorted twice:
14 * once by name and once by grade.
15 */
16
17 // Create the array:
18 // Array structure:
19 // studentID => array ('name' => 'Name', 'grade' => XX.X)
20 $students = array (
21 256 => array ('name' => 'Jon', 'grade' => 98.5),
22 2 => array ('name' => 'Vance', 'grade' => 85.1),
23 9 => array ('name' => 'Stephen', 'grade' => 94.0),

Multidimensional Arrays
24 364 => array ('name' => 'Steve', 'grade' => 85.1),
25 68 => array ('name' => 'Rob', 'grade' => 74.6)
26 );
27
28 // Name sorting function:
29 function name_sort ($x, $y) {
30 return strcasecmp($x['name'], $y['name']);
31 }
32
33 // Grade sorting function:
34 // Sort in DESCENDING order!
35 function grade_sort ($x, $y) {
36 return ($x['grade'] < $y['grade']);
37 }
38
39 // Print the array as is:
40 echo '<h3>Array As Is</h3><pre>' . print_r($students, 1) . '</pre>';
41
42 // Sort by name:
43 uasort ($students, 'name_sort');
44
45 // Print the array now:
46 echo '<h3>Array Sorted By Name</h3><pre>' . print_r($students, 1) . '</pre>';
47
48 // Sort by grade:
49 uasort ($students, 'grade_sort');
50
51 // Print the array now:
52 echo '<h3>Array Sorted By Grade</h3><pre>' . print_r($students, 1) . '</pre>';
53
54 ?>
55 </body>
56 </html>

5
Chapter 1

3. Define the name sorting function.


function name_sort ($x, $y) {
return strcasecmp($x[‘name’],
➝ $y[‘name’]);
}
The strcasecmp() function returns a
number—negative, 0, or positive—indi-
cating how similar two strings are. If a
negative value is returned, the first string
comes before the second alphabetically; if
a positive value is returned, the second
string comes first. If 0 is returned, the
strings are the same.
4. Define the grade sorting function.
function grade_sort ($x, $y) {
return ($x[‘grade’] <
➝ $y[‘grade’]);
}
Figure 1.5 Failure to use uasort() would
Multidimensional Arrays

This example is like the demo in the cause the keys, which store meaningful
introduction to these steps. One signifi- values (see Script 1.1), to be lost.
cant difference is that I want to perform
a descending sort, so that the highest
grades are listed first. This is easily
accomplished: change the comparison
operator from greater than to less than.
5. Print the array as it’s initially defined.
echo ‘<h3>Array As Is</h3><pre>’ .
➝ print_r($students, 1) . ‘</pre>’;
For improved legibility, I’ll use the <pre>
tags and print_r() to quickly reveal the
arrays’ structure and values.
6. Sort the array by name and print the
results.
uasort ($students, ‘name_sort’);
echo ‘<h3>Array Sorted By
➝ Name</h3><pre>’ .
➝ print_r($students, 1) . ‘</pre>’;
Here the uasort() function is used so
that the keys—the student IDs—are not
lost. Figure 1.5 shows the result if just
usort() was used instead.

6
Advanced PHP Techniques

7. Sort the array by grade and print the 8. Complete the page.
results. ?>
uasort ($students, ‘grade_sort’); </body>
echo ‘<h3>Array Sorted By </html>
➝ Grade</h3><pre>’ .
➝ print_r($students, 1) . ‘</pre>’;
9. Save the file as sort.php, place it in your
Web directory, and test in your Web
browser (Figures 1.6 and 1.7).

Multidimensional Arrays

Figure 1.6 The initial array and sorted Figure 1.7 The array sorted by grade, in
by name. descending order (this is the same Web
page as in Figure 1.6, but it couldn’t all
fit in one screenshot).

7
Chapter 1

Database-driven arrays
If you think about it, most database queries
return a multidimensional array (Figure 1.8).
If the query results are immediately sent to
the Web browser one at a time, the multidi-
mensional structure doesn’t add any compli-
cation to your code. However, if you need to
do something more elaborate with the results, Figure 1.8 Selecting multiple columns from multiple
you’ll need a way to comprehend and man- rows in a database results in a multidimensional
age the nested structure. array.

For this example, I want to create a database-


driven, Web-based to-do list system. If the
to-do list were one-dimensional, this wouldn’t
be that hard. But the list should be nestable,
where each item can have multiple steps.
The result will be a tree-like structure, where
each branch can have its own offshoots
(Figure 1.9).
Multidimensional Arrays

Figure 1.9 How a nested to-do list looks as a tree.

8
Advanced PHP Techniques

The database required by this is surprisingly


simple (Table 1.1). The trick is that each item
has a parent_id attribute. If an item is a sub-
step, its parent_id would be the task number
of the item that it falls under (Figure 1.10).
If an item is not a substep, its parent_id
would be 0. It’s a very simple setup, but han-
dling this in PHP will take some effort.
Over the next few pages, you’ll create the
Figure 1.10 This table represents the same data as in database table and a PHP script for adding
Figures 1.8 and 1.9. There will be a pseudo–foreign new tasks. In the next sections of the chap-
key–primary key relationship between the task_id ter, you’ll see how to use recursive functions
and parent_id columns.
to handle the multidimensional array.

Multidimensional Arrays

Table 1.1 This one database table is all that is required to manage a nested to-do list.

The tasks Table


Column Name Ty p e Extr a

task_id INT UNSIGNED AUTO_INCREMENT, Primary Key


parent_id INT UNSIGNED NOT NULL, DEFAULT 0
task VARCHAR(100) NOT NULL
date_added TIMESTAMP NOT NULL
date_completed TIMESTAMP

9
Chapter 1

To create the database:


1. Access MySQL using the mysql client or
other interface.
I’ll be using MySQL in this example, but
you can use any database application, of
course. To create the table, I’ll use the
command-line mysql client, but you could Figure 1.11 The table will be created within the test
use phpMyAdmin or one of MySQL’s database.
graphical interfaces instead.
2. Select the test database (Figure 1.11).
USE test;
I’ll just throw this one table within the
test database, as it’s not part of any
larger application. You can put it in a
different database, if you prefer.
3. Create the table (Figure 1.12).
CREATE TABLE tasks (
task_id INT UNSIGNED NOT NULL
Multidimensional Arrays

➝ AUTO_INCREMENT, Figure 1.12 Creating the tasks table.

parent_id INT UNSIGNED NOT NULL


➝ DEFAULT 0,
task VARCHAR(100) NOT NULL,
date_added TIMESTAMP NOT NULL,
date_completed TIMESTAMP,
PRIMARY KEY (task_id),
INDEX parent (parent_id),
INDEX added (date_added),
INDEX completed (date_completed)
);
The task_id is an automatically incre-
mented primary key. The value will also
be used as the parent_id if a task is a sub-
step. The task itself goes into a VAR-
CHAR(100) column, which you could also
define as a text type if you wanted to
allow for longer descriptions. Two time-
stamp columns round out the table, one
documenting when the task was added
and another to indicate its completion.
Three standard indexes are placed on
columns that might be used in queries.

10
Advanced PHP Techniques

4. Test the table by adding a dummy task


(Figure 1.13):
INSERT INTO tasks (task) VALUES
➝ (‘Must Do This!’);
SELECT * FROM tasks;

Figure 1.13 The tasks will normally be added using a For a simple task that’s not a subset of
PHP script, but a test insertion is run just to make another task, only the one column needs
sure everything is on the up and up. to be provided with a value. The SELECT
query confirms that the parent_id,
date_added, and date_completed columns
are automatically given default values
(0000-00-00 00:00:00 is the TIMESTAMP
equivalent of 0).
5. Empty the table.
TRUNCATE tasks;

Multidimensional Arrays

11
Chapter 1

To add tasks to the database: <head>


<meta http-equiv=”content-type”
1. Begin a new PHP script in your text edi-
➝ content=”text/html; charset=
tor or IDE, starting with the HTML
➝ iso-8859-1” />
(Script 1.2).
<title>Add a Task</title>
<!DOCTYPE html PUBLIC “-//W3C//
➝ DTD XHTML 1.0 Transitional//EN” </head>

“http://www.w3.org/TR/xhtml1/DTD/ <body>
➝ xhtml1-transitional.dtd”> <?php # Script 1.2 - add_task.php
<html xmlns=”http://www.w3.org/1999/ continues on page 14
➝ xhtml” xml:lang=”en” lang=”en”>

Script 1.2 Tasks are added to the database using this script. Tasks can even be filed under other tasks using the
drop-down menu.

1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"


2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4 <head>
5 <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
6 <title>Add a Task</title>
Multidimensional Arrays

7 </head>
8 <body>
9 <?php # Script 1.2 - add_task.php
10
11 /* This page adds tasks to the tasks table.
12 * The page both displays and handles the form.
13 */
14
15 // Connect to the database:
16 $dbc = @mysqli_connect ('localhost', 'username', 'password', 'test') OR die ('<p>Could not
connect to the database!</p></body></html>');
17
18 // Check if the form has been submitted:
19 if (isset($_POST['submitted']) && !empty($_POST['task'])) {
20
21 // Sanctify the input...
22
23 // The parent_id must be an integer:
24 if (isset($_POST['parent_id'])) {
25 $parent_id = (int) $_POST['parent_id'];
26 } else {
27 $parent_id = 0;
28 }
29
30 // Escape the task:
31 // Assumes Magic Quotes are off!
32 $task = mysqli_real_escape_string($dbc, $_POST['task']);
33
34 // Add the task to the database.
35 $q = "INSERT INTO tasks (parent_id, task) VALUES ($parent_id, '$task')";
36 $r = mysqli_query($dbc, $q);
37
38 // Report on the results:
39 if (mysqli_affected_rows($dbc) == 1) {

12
Advanced PHP Techniques

Script 1.2 continued

40 echo '<p>The task has been added!</p>';


41 } else {
42 echo '<p>The task could not be added!</p>';
43 }
44
45 } // End of submission IF.
46
47 // Display the form:
48 echo '<form action="add_task.php" method="post">
49 <fieldset>
50 <legend>Add a Task</legend>
51
52 <p>Task: <input name="task" type="text" size="60" maxlength="100" /></p>
53
54 <p>Parent Task: <select name="parent_id"><option value="0">None</option>
55 ';
56
57 // Retrieve all the uncompleted tasks:
58 $q = 'SELECT task_id, parent_id, task FROM tasks WHERE date_completed="0000-00-00 00:00:00"
ORDER BY date_added ASC';
59 $r = mysqli_query($dbc, $q);
60
61 // Also store the tasks in an array for use later:
62 $tasks = array();
63

Multidimensional Arrays
64 while (list($task_id, $parent_id, $task) = mysqli_fetch_array($r, MYSQLI_NUM)) {
65
66 // Add to the select menu:
67 echo "<option value=\"$task_id\">$task</option>\n";
68
69 // Add to the array:
70 $tasks[] = array('task_id' => $task_id, 'parent_id' => $parent_id, 'task' => $task);
71
72 }
73
74 echo '</select></p>
75
76 <input name="submitted" type="hidden" value="true" />
77 <input name="submit" type="submit" value="Add This Task" />
78
79 </form>
80 </fieldset>
81 ';
82
83 // Sort the tasks by parent_id:
84 function parent_sort ($x, $y) {
85 return ($x['parent_id'] > $y['parent_id']);
86 }
87 usort ($tasks, 'parent_sort');
88
89 // Display all the tasks:
90 echo '<h3>Current To-Do List</h3><ul>';
91 foreach ($tasks as $task) {
92 echo "<li>{$task['task']}</li>\n";
93 }
94 echo '</ul>';
95 ?>
96 </body>
97 </html>

13
Chapter 1

2. Connect to the database.


$dbc = @mysqli_connect (‘localhost’,
➝ ‘username’, ‘password’, ‘test’) OR
➝ die (‘<p>Could not connect to the
➝ database!</p></body></html>’);
I’ll be using MySQL and the Improved Figure 1.14 If a database connection cannot be made,
MySQL functions in this script. These are this is the result.
available as of PHP 5 and MySQL 4.1. If
you are using older versions of either, you’ll
need to change the code accordingly.
If a database connection couldn’t be
made, an error is printed and the script
terminated (Figure 1.14).
3. Check if the form has been submitted.
if (isset($_POST[‘submitted’]) &&
➝ !empty($_POST[‘task’])) { Figure 1.15 The HTML form for adding tasks.
The form (Figure 1.15) has one main
text box and a drop-down menu. To test
for the form’s submission, the conditional
Multidimensional Arrays

checks that a hidden input named sub-


mitted is set and that the text box
(named task) isn’t empty.
4. Ensure that the parent_id value is an
integer.
if (isset($_POST[‘parent_id’])) {
$parent_id = (int)
➝ $_POST[‘parent_id’];
} else {
$parent_id = 0;
}
The parent_id value is another task’s
task_id. It will come from the drop-down
menu, which means that it should be an
integer. But one shouldn’t make assump-
tions (because if someone hacked the
form to send text as the parent_id, it
would break the query), so this variable is
typecast to an integer. If a valid value is
submitted, this casting will have no effect.
Any invalid values will be turned into 0.
The same applies if the script does not
receive a $_POST[‘parent_id’] value.

14
Advanced PHP Techniques

5. Secure the task value. 8. Complete the submission conditional


$task = and start the form.
➝ mysqli_real_escape_string($dbc, } // End of submission IF.
➝ $_POST[‘task’]); echo ‘<form action=”add_task.php”
The mysqli_real_escape_string() func- ➝ method=”post”>
tion will make whatever submitted task <fieldset>
value safe to use in the query. <legend>Add a Task</legend>
6. Add the task to the database. <p>Task: <input name=”task” type=
$q = “INSERT INTO tasks (parent_id, ➝ ”text” size=”60” maxlength=”100”
➝ task) VALUES ($parent_id, ➝ /></p>
➝ ‘$task’)”; <p>Parent Task: <select name=
$r = mysqli_query($dbc, $q); ➝ ”parent_id”><option value=
➝ ”0”>None</option>
This query differs from the test query
run earlier in that it also populates the ‘;
parent_id field in the table. The form has one text input and one
drop-down menu. The menu will be pop-
7. Report on the query results.
ulated from the list of existing tasks. The
if (mysqli_affected_rows($dbc) == 1)
first possible value will be 0, for tasks that
{
are not subservient to other tasks.

Multidimensional Arrays
echo ‘<p>The task has been
➝ added!</p>’;
9. Retrieve all the uncompleted tasks.
$q = ‘SELECT task_id, parent_id, task
} else {
➝ FROM tasks WHERE its date_
echo ‘<p>The task could not be
➝ completed=”0000-00-00 00:00:00”
➝ added!</p>’;
➝ ORDER BY date_added ASC’;
}
$r = mysqli_query($dbc, $q);
The query returns three pieces of infor-
mation for every uncompleted task
(once a task has been completed, its
date_completed column would have a
nonzero value). The task_id and the task
itself will be used in the drop-down
menu. The parent_id will be used later
to nest the tasks.
continues on next page

15
Chapter 1

10. Create an array for storing the tasks.


$tasks = array();
This script will list all the tasks twice:
once in the drop-down menu and once
after the form (Figure 1.16). This array
will store the second list.
11. Retrieve a database record and use it
accordingly.
while (list($task_id, $parent_id,
➝ $task) = mysqli_fetch_
➝ array($r, MYSQLI_NUM)) {
echo “<option value=\
➝ ”$task_id\”>$task</option>\n”;
$tasks[] = array(‘task_id’ =>
➝ $task_id, ‘parent_id’ =>
➝ $parent_id, ‘task’ => $task); Figure 1.16 The page contains the list of tasks two
} times.

Within the while loop the retrieved


Multidimensional Arrays

record is used to populate the drop-


down menu (Figure 1.17) and is also
stored in the $tasks array. This array will
be multidimensional.
12. Complete the form.
echo ‘</select></p>
<input name=”submitted” type= Figure 1.17 The PHP-generated HTML source code for
➝ ”hidden” value=”true” /> the drop-down menu.

<input name=”submit” type=”submit”


➝ value=”Add This Task” />
</form>
</fieldset>
‘;
The hidden input here is a trick I use
to check for a form’s submission. Doing
this is sometimes necessary as just
pressing Enter within Internet Explorer
for Windows will submit a form without
ever setting the $_POST[‘submit’]
variable.

16
Advanced PHP Techniques

13. Sort the tasks by parent_id.


function parent_sort ($x, $y) {
return ($x[‘parent_id’] >
➝ $y[‘parent_id’]);
}
usort ($tasks, ‘parent_sort’);
The parent_id value is what separates
primary tasks from secondary ones,
so working with this value in PHP is
important. Using the information dis-
cussed earlier in the chapter, a user-
defined function will sort the multidimen-
sional array.
Figure 1.18 Adding a new task that’s not linked to 14. Display the full list of tasks.
another task. echo ‘<h3>Current To-Do
➝ List</h3><ul>’;
foreach ($tasks as $task) {
echo “<li>{$task[‘task’]}

Multidimensional Arrays
➝ </li>\n”;
}
echo ‘</ul>’;
This loop will display each task in order
of its parent_id. This is the first step
toward making the list shown in Figure 1.1,
although as you can see in Figure 1.16,
the list isn’t organized as it should be.
This will be solved later in the chapter.
15. Complete the page.
?>
</body>
</html>

Figure 1.19 Adding a task that’s a subset of an 16. Save the file as add_task.php, place it in
existing task. your Web directory, and test in your Web
browser (Figures 1.18 and 1.19).
✔ Tip
■ If you wanted to implement this idea in a
live site, one improvement you could
make would be the ability to add multi-
ple tasks at once. I’ll provide further tips
on fleshing out this example over the
course of the chapter.
17
Chapter 1

The lack of a condition that determines


Advanced Function when to stop execution of the function cre-
Definitions ates a big programming no-no, the infinite
loop. Compare that function to this one:
Being able to define and use your own func-
function count_to_100 ($n) {
tions is integral to any programming lan-
guage. After even a modicum of PHP experi- if ($n <= 100) {
ence, you’ve no doubt created many. But echo $n . '<br />';
there are three potential features of user- $n++;
defined functions that arise in more count_to_100 ($n);
advanced programming. These are:
}
◆ Recursive functions }
◆ Static variables count_to_100 (1);

◆ Accepting values by reference This function will continue to call itself until
$n is greater than 100, at which point it will
While not often used, sometimes these con- stop executing the function. (That’s obvi-
cepts are indispensable. In discussing and ously a trivial use of this concept; a loop
demonstrating these first two concepts, I’ll would do the same thing.)
continue to build upon the tasks example
Advanced Function Definitions

just begun in the chapter. Recursive functions are necessary when you
have a process that may be followed to an
Recursive functions unknown depth. For example, a script that
searches through a directory may have to
Recursion is the act of a function calling
search through any number of subdirecto-
itself.
ries. Or an array might have an unknown
function somefunction() {
number of dimensions....
// Some code.
With the tasks table created earlier in the
somefunction();
chapter, retrieving and displaying all the
// Possible other code.
tasks is not hard (see Figures 1.17 and 1.18).
} However, the method used in add_task.php
The end result is that your functions can act (Script 1.2) does not properly nest the tasks
both as originally intended and as a loop. like that in Figure 1.1. To accomplish that
The one huge warning when using this tech- desired end, a multidimensional array and a
nique is to make sure your function has an recursive function are required.
“out” clause. For example, the following code
will run ad infinitum:
function add_one ($n) {
$n++;
add_one ($n);
}
add_one (1);

18
Advanced PHP Techniques

To use recursion: <head>


<meta http-equiv=”content-type”
1. Begin a new PHP script in your text edi-
➝ content=”text/html; charset=
tor or IDE, starting with the HTML
➝ iso-8859-1” />
(Script 1.3).
<title>View Tasks</title>
<!DOCTYPE html PUBLIC “-//W3C//
➝ DTD XHTML 1.0 Transitional//EN” </head>

“http://www.w3.org/TR/xhtml1/DTD/ <body>
➝ xhtml1-transitional.dtd”> <h3>Current To-Do List</h3>
<html xmlns=”http://www.w3.org/1999/ <?php # Script 1.3 - view_tasks.php
➝ xhtml” xml:lang=”en” lang=”en”>
continues on page 21

Script 1.3 One recursive function and a potentially bottomless multidimensional array will properly display the
nested list of tasks.

1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

Advanced Function Definitions


2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4 <head>
5 <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
6 <title>View Tasks</title>
7 </head>
8 <body>
9 <h3>Current To-Do List</h3>
10 <?php # Script 1.3 - view_tasks.php
11
12 /* This page shows all existing tasks.
13 * A recursive function is used to show the
14 * tasks as nested lists, as applicable.
15 */
16
17 // Function for displaying a list.
18 // Receives one argument: an array.
19 function make_list ($parent) {
20
21 // Need the main $tasks array:
22 global $tasks;
23
24 // Start an ordered list:
25 echo '<ol>';
26
27 // Loop through each subarray:
28 foreach ($parent as $task_id => $todo) {
29

(script continues on next page)

19
Chapter 1

Script 1.3 continued

30 // Display the item:


31 echo "<li>$todo";
32
33 // Check for subtasks:
34 if (isset($tasks[$task_id])) {
35
36 // Call this function:
37 make_list($tasks[$task_id]);
38
39 }
40
41 // Complete the list item:
42 echo '</li>';
43
44 } // End of FOREACH loop.
45
46 // Close the ordered list:
47 echo '</ol>';
48
49 } // End of make_list() function.
Advanced Function Definitions

50
51
52 // Connect to the database:
53 $dbc = @mysqli_connect ('localhost', 'username', 'password', 'test') OR die ('<p>Could not
connect to the database!</p></body></html>');
54
55 // Retrieve all the uncompleted tasks:
56 $q = 'SELECT task_id, parent_id, task FROM tasks WHERE date_completed="0000-00-00 00:00:00"
ORDER BY parent_id, date_added ASC';
57 $r = mysqli_query($dbc, $q);
58
59 // Initialize the storage array:
60 $tasks = array();
61
62 while (list($task_id, $parent_id, $task) = mysqli_fetch_array($r, MYSQLI_NUM)) {
63
64 // Add to the array:
65 $tasks[$parent_id][$task_id] = $task;
66
67 }
68
69 // For debugging:
70 //echo '<pre>' . print_r($tasks,1) . '</pre>';
71
72 // Send the first array element
73 // to the make_list() function:
74 make_list($tasks[0]);
75
76 ?>
77 </body>
78 </html>

20
Advanced PHP Techniques

2. Begin defining a function.


function make_list ($parent) {
global $tasks;
echo ‘<ol>’;
The purpose of the function will be
to display an array of items in an
ordered list:
<ol>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ol>
This function will take one argument,
which will always be an array. Within the
function, the $tasks array (the main
array) needs to be available—you’ll soon
see why. Then the ordered list is begun.

Advanced Function Definitions


3. Loop through the array, printing
each item.
foreach ($parent as $task_id
➝ => $todo) {
echo “<li>$todo”;
A foreach loop will go through the array,
printing each item within <li> tags.
Those are begun here.
continues on next page

21
Chapter 1

4. Check if any subtasks exist.


if (isset($tasks[$task_id])) {
make_list($tasks[$task_id]);
}
This is the most important part of the
script. The tasks retrieved from the data-
base will be tossed into a multidimen-
sional array like that in Figure 1.20. For
the main array, each key is a parent_id
and the elements are arrays of tasks that
fall under that parent_id. So after print-
ing the initial <li> task, the function
needs to check if this task has any sub-
tasks; in other words: is there an array
element in $tasks whose key is this task
Figure 1.20 The PHP script takes the tasks
ID? If so, then this function should be from the database and creates this
called again, sending that other part of multidimensional array.
the array (the element whose key is this
Advanced Function Definitions

task_id and whose value is an array of


subtasks) as the argument. That will
result in the code:
<ol>
<li>Item 1</li>
<li>Item 2
<ol>
<li>Subitem 1</li>
<li>Subitem 2</li>
</ol>
</li>
<li>Item 3</li>
</ol>

5. Complete the foreach loop and the


function.
echo ‘</li>’;
} // End of FOREACH loop.
echo ‘</ol>’;
} // End of make_list() function.

22
Advanced PHP Techniques

6. Connect to the database. The $tasks array will store every task.
$dbc = @mysqli_connect (‘localhost’, Figure 1.20 shows the final structure. As
➝ ‘username’, ‘password’, ‘test’) OR described in Step 4, the array’s outer-
➝ die (‘<p>Could not connect to the most key is the parent_id value from
➝ database!</p></body></html>’); the table. The value of this outermost
With the recursive function defined, the array is an array of the tasks with that
parent_id.
rest of the script needs to retrieve all the
tasks, organize them in an array, and then 9. Add a debugging line, if desired.
call the make_list() function. //echo ‘<pre>’ . print_r($tasks,1) .
7. Define and execute the query. ➝ ‘</pre>’;

$q = ‘SELECT task_id, parent_id, task When dealing with multidimensional


➝ FROM tasks WHERE arrays, it’s vitally important to know and
date_completed=”0000-00-00 00:00:00” understand the structure you’re working
➝ ORDER BY parent_id, date_added with. When you uncomment this line (by
➝ ASC’; removing the two slashes), the script will
$r = mysqli_query($dbc, $q);
print the array like you see in Figure 1.20.
The query retrieves three pieces of infor- 10. Call the make_list() function, sending it
mation for each task: its ID, its parent_id, the array of top-level tasks.

Advanced Function Definitions


and the task itself. The conditional make_list($tasks[0]);
means that only noncompleted tasks are Although the $tasks variable is a multi-
selected. The results are also ordered by dimensional array, the make_list() func-
the parent_id, so that every top-level task tion needs to be called only once, send-
(with a parent_id of 0) is returned first. A ing it the first array element. This ele-
secondary ordering by the date_added ment’s value is an array of tasks whose
returns the tasks in the order they were parent_id is 0. Within the function, for
added (an assumption being that’s how each of these tasks, a check will see if
they are prioritized). there are subtasks. So the function will
8. Add each task to an array. end up accessing every task thanks to its
$tasks = array();
recursive nature.
while (list($task_id, $parent_id, 11. Complete the page.
➝ $task) = mysqli_fetch_ ?>
➝ array($r, MYSQLI_NUM)) {
</body>
$tasks[$parent_id][$task_id]
</html>
➝= $task;
}
continues on next page

23
Chapter 1

12. Save the file as view_tasks.php, place it


in your Web directory, and test in your
Web browser (Figure 1.21).
13. Add some more subtasks and retest in
your Web browser (Figure 1.22).
✔ Tips
■ The PHP manual suggests that you
should avoid any recursive function that
may call itself over 100 to 200 times.
Doing so could crash the script or the Figure 1.21 The page of tasks, as a bunch of
nested lists.
Web server.
■ This page does assume that some tasks
were returned by the database. You may
want to add a conditional checking that
$tasks isn’t empty prior to calling the
make_list() function.
Advanced Function Definitions

Figure 1.22 There is no limit to the number of


subtasks that this system supports.

24
Advanced PHP Techniques

Using static variables


When working with recursion or, in fact,
any script in which the same function may
be called multiple times, you might want to
consider using the static statement. static
forces the function to remember the value of
a variable from function call to function call,
without using global variables. The example
count_to_100() function (see the preceding
section of this chapter) could be rewritten
like so with the same result:
function count_to_100 () {
static $n = 1;
if ($n <= 100) {
echo $n . '<br />';
$n++;
count_to_100 ();

Advanced Function Definitions


}
Completing This Example }
This example was primarily written to count_to_100 ();
demonstrate multidimensional arrays and
Of course, that’s not a very useful implemen-
recursive functions. Still, it’s a nice exam-
tation of the concept. The very astute reader
ple and worth implementing in a live site
may have wondered how I achieved the result
(the ability to nest tasks is great). If you
in Figure 1.3. Showing the values being com-
wanted to do so, one feature you’d likely
pared is not hard, but counting the iterations
need is the ability to mark a task as com-
requires the use of static. Toward this end,
pleted. An example later in the chapter
sort.php will be modified.
will do just that. Another alteration would
be to change the add_task.php page so
that the drop-down menu reflects the
hierarchy as well.
Another likely addition would be the
ability to add multiple tasks at once. And
you may want to consider an edit task
option. While you’re at it, the view tasks
page could have a link that passes a
value in the URL indicating whether all
tasks should be displayed or just uncom-
pleted ones. These are just some ideas.
Turn to the book’s supporting forum
(www.dmcinsights.com/phorum/) for
assistance and more!

25
Chapter 1

To use static variables: Three lines of code have been added to


the function. The first is the declaration
1. Open sort.php (Script 1.1) in your text of a static variable called $count. It’s ini-
editor or IDE. tially set to 1, but that assignment only
2. Modify the name_sort() function to read applies the first time this function is
(Script 1.4): called (because it’s a static variable).
function name_sort ($x, $y) {
Then the iteration number is printed
(how many times this function has
static $count = 1;
been called), along with the values being
echo “<p>Iteration $count:
compared. Finally, the $count variable is
➝ {$x[‘name’]} vs. {$y[‘name’]}
incremented.
➝ </p>\n”;
$count++;
continues on page 28

return strcasecmp($x[‘name’],
➝ $y[‘name’]);

Script 1.4 This modified version of the sorting script will reveal how many times each sorting function is invoked,
thanks to a static variable.
Advanced Function Definitions

1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"


2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4 <head>
5 <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
6 <title>Sorting Multidimensional Arrays</title>
7 </head>
8 <body>
9 <?php # Script 1.4 - sort2.php
10
11 /* This page creates a multidimensional array
12 * of names and grades.
13 * The array is then sorted twice:
14 * once by name and once by grade.
15 * A static variable has been added to both
16 * functions to see how many times they are called.
17 */
18
19 // Create the array:
20 // Array structure:
21 // studentID => array ('name' => 'Name', 'grade' => XX.X)
22 $students = array (
23 256 => array ('name' => 'Jon', 'grade' => 98.5),

26
Advanced PHP Techniques

Script 1.4 continued

24 2 => array ('name' => 'Vance', 'grade' => 85.1),


25 9 => array ('name' => 'Stephen', 'grade' => 94.0),
26 364 => array ('name' => 'Steve', 'grade' => 85.1),
27 68 => array ('name' => 'Rob', 'grade' => 74.6)
28 );
29
30 // Name sorting function:
31 function name_sort ($x, $y) {
32 static $count = 1;
33 echo "<p>Iteration $count: {$x['name']} vs. {$y['name']}</p>\n";
34 $count++;
35 return strcasecmp($x['name'], $y['name']);
36 }
37
38 // Grade sorting function:
39 // Sort in DESCENDING order!
40 function grade_sort ($x, $y) {
41 static $count = 1;
42 echo "<p>Iteration $count: {$x['grade']} vs. {$y['grade']}</p>\n";

Advanced Function Definitions


43 $count++;
44 return ($x['grade'] < $y['grade']);
45 }
46
47 // Print the array as is:
48 echo '<h3>Array As Is</h3><pre>' . print_r($students, 1) . '</pre>';
49
50 // Sort by name:
51 uasort ($students, 'name_sort');
52
53 // Print the array now:
54 echo '<h3>Array Sorted By Name</h3><pre>' . print_r($students, 1) . '</pre>';
55
56 // Sort by grade:
57 uasort ($students, 'grade_sort');
58
59 // Print the array now:
60 echo '<h3>Array Sorted By Grade</h3><pre>' . print_r($students, 1) . '</pre>';
61
62 ?>
63 </body>
64 </html>

27
Chapter 1

3. Modify the grade_sort() function


to read:
function grade_sort ($x, $y) {
static $count = 1;
echo “<p>Iteration $count:
➝ {$x[‘grade’]} vs.
➝ {$y[‘grade’]}</p>\n”;
$count++;
return ($x[‘grade’] <
➝ $y[‘grade’]);
}
The same three lines of code that were
added to name_sort() are added to
grade_sort(), except the key being
compared here is grade, not name.
4. Save the file as sort2.php, place it in your
Web directory, and test in your Web
Advanced Function Definitions

browser (Figures 1.23 and 1.24).


Figure 1.23 Sorting the original five-element
array by name requires six calls of the sorting
function.

Figure 1.24 Sorting the same array by grade


also requires six iterations.

28
Random documents with unrelated
content Scribd suggests to you:
Ah many a mansion shall we visit in our Father’s home,
As we fly beneath his banner, with ages and ages to roam.

’Tis a fathomless universe, but the plan eternal is one,


On which good men and angels may forever run,
O’er many a threatening torrent here, chasm, wide and great;
And ever man and gods shall their new links create—
Some for service and for song, and some for wonder and delight;
And some time, somewhere the Bridge—to everlasting light.

THE MIGHT OF MATUTINAL MUSIC


When awaking from dreams completely refresht,
My body reclining still;
With a soul alive and a heart at rest,
And master too of my will—

When the sun doth cast ambitious rays,


Foretelling afar his race;
And my heart is clothed with the garment of praise
By an all pervading grace—

When I hear the psalm of the gifted Thrush,


With a song of a mountain stream,
And a child’s sweet laugh, while the morn’s a-flush,
When Nature is all a-gleam—

Ah, then my soul is thrilled with delight


And my mind sweeps every sea,
’Tis then I possess my musical might,
And the angels visit me.
Photos by the Author.

A PERPETUAL KING
In a King on a throne and a King there to stay,
You’ve a friendly old monarch who’s ever upright.
There are blessings for you and the men far away,
In a King on a throne and a King there to stay.
His robe is pure white, but the proud make it gay;
Ah, what mercy, what power and amazing foresight
In a King on a throne and a King there to stay—
You’ve a friendly old monarch who’s ever upright!

THE COTTON GIN


At a cotton gin the King’s made thin,
Yet never shows the least chagrin,
In his sunny home in Dixie’s land,
That rich and poor may live and win.

He’s trifled with, but will not sin


Amongst his subjects, nor his kin,
Although he feels the iron band
At a cotton gin.

More just the King than a mandarin,


And I often think the cherubin
Would like themselves to understand
His long, rich round, and then command
At a cotton gin.

THE COTTON MILL


In Southern climes and the monarch’s mill
Weave many a spindle and loom;
And lake and lawn, with art’s own skill,
In Southern climes and the monarch’s mill;
Yes, church and school and much to fill
The mind with hope and buoyant bloom—
In Southern climes and the monarch’s mill,
Weave many a spindle and loom.
MY OWN LITTLE GIRL
I’ve covered many and many a mile;
I’ve seen the setting of many a sun;
I have oft been charmed by the infant’s smile,
Pondering gladly life’s journey begun.

I’ve met with the great and small not a few;


I’ve sat at the feet of the learned knight,
I’ve stood on the stage with Gentile and Jew,
Addressing the throng by day and by night.

I’ve witnessed the way of the meek and wise,


Ah, the vanishing joy of the greedy;
And more has come under my eager eyes,
Seeing the re-filled cup of the needy.

But never a joy I’ve felt was my own—


Which bachelor old and maiden know not—
Is equal to that when I return home,
My humble home, yet delectable spot,

And take to my heart my own little girl,


All laughter and love—the joy of my life.
Right here let me rest, far away the mad whirl,
And feast on pure love, free from all strife.
My own little girl,
My priceless pearl,
With dance of delight,
A musical sprite—
My Artena.

With hair of pure gold,


With heart never cold,
Who learns with a zest,
And strives for the best—
My Artena.

Ten years old today—


And never to decay—
May she aye be sweet,
And at length complete,
My Artena.

MY BUTTERFLY[11]
My Butterfly, my wondrous Butterfly,
Forsaking temple great, thou choosest me,
When form and burnished wings arrive—I see
With joy, as ne’er before, thy glory nigh.
We journey through the city, thou and I,
In store and street with joined hearts and free,
While men admire thy trust and amity,
But wonder not in thee, nor question why.

At length thy wings bedecked with Heaven’s art,


Begin to wave, as Nature planned, and east
Thou farest forth with grace, but to my heart
Thou ever clingest still. Fly on and feast
On nectar such as men have never wrought;
In thee is trust and love and, why not, thought?

Was That Somebody I?


O child of hope, why left to go astray,
And rend this heart of mine?
Some one knew not, nor cared what ruthless way
You wend—once babe benign—
Was that somebody I?

If God, with perfect heart, loved you, my child,


And to Jesus likened thee—
Why so favored first, now sad and wild?
Who failed to love? Ah me!
Was that somebody I?

One said he loved the Christ and all of his;


He read the Word and prayed;
Believed that one the cruel creed, “What is,
Is best?” And so you strayed—
Was that somebody I?

At home neglected, nowhere a faithful friend,


You listless wandered on;
Till fool or knave declared: “You’re bad, your end
Looms dark—a criminal born!”
Was that somebody I?

Despised yet more—the Christ and thee—then crime!


You bore with shame the chains!
Your training and your arts, in Hell’s own clime,
Went on with damning drains—
Great Heaven! was it I?
Did I neglect you, child, my Father’s child,
I judge, and send you down?
Myself at ease, while you were curst, reviled—
No aid gave I, no crown?
Then Christ must pass me by!

MY SABBATH SERMON
A growing mocker in a maple tree,
Poured forth first notes with youthful glee;
Like an untried poet born to sing,
He’s proving gifts which fame will bring.

And musing on that Sabbath morn,


With body weary, heart forlorn,
The music of the blithesome bird
Inspired my mind itself to gird
With faith and courage, hope and love,
Beguiling my heart to leap above.
’Tis ever thus, some primal song
Doth make us gentle, brave and strong;

And trustful too, till we can see


With eyes of Him of Galilee—
Sweet Sabbath notes from the amateur,
Which filled my soul with a speedy cure.

The bird will better sing, and I


Shall carol sweetly by and by;
After earth’s songs on vernal sod,
Then high above in the choir of God.

What wondrous choir—how vast, how bright,


With suns and stars, and yet greater Light.
They also sing, as ever they shine,
With a strength of love that is divine.

Yon rolling plain and mountain peak,


Or surging sea and bounding creek;
Or budding rose and lustrous star—
All bid us rise to an avatar,

Above rich valley, and hill’s proud crest,


Above things seen to heaven’s best—
To perfect ones, with the angel throng,
O’er topless hills in endless song!

PILOT MOUNTAIN
O Jomeokee, thou everlasting guide,
Lifting high thyself, a tower strong
For passing men, and deathless hills around;
For Yadkin and on-flowing Ararat,
Bathing thy feet in humblest gratitude;
Thy lofty head, embraced by cooling clouds,
Gives something forth that’s rich, and unto all—
O Pilot old, thy secret bare to me.

Tell me when thy origin and where;


What hidden womb ambitious gave thee birth;
Bear witness thou to all both seen and heard
By thee from first to last; from primal man,
To Renfro Indian tribe, who spake thy praise
In by-gone years, and poet last who sang
Thy glory—O eternal Pilot speak!

As mute thou art as mighty and sublime,


Like unto all that’s great and strong and good—
Forever still midst Surrey’s joyful hills;
Yet to men thou bringest a message deep;
To Indian, symbol of the Spirit Great;
To me, the varied, potent word of God.

A View of “Big Pinnacle” on Pilot


Mountain, in Surrey County, N. C.
Picture by the Author.

Majestic lord of all, to thee on high,


The struggling towns appear as vying dwarfs;
The rivers like to circling, creeping snakes;
Valleys, rich and broad, thy gardens are
Imperial—and all thine honors sing.

Sons of chiefs long vanquished played and danced


Before thy face; again the fathers prayed,
Their plea ascending, swift as thought, to Him
Who guided Abram ’mongst Judean hills.

What heart-breaks knowest thou of sire and son?


Of lover and beloved, of hate and hope?
Deepest depths and uplift to the heights?
I hear the music of thy hidden heart,
Sorrow’s song, in-wrought with joy that’s pure,
The process endless of the urging Cross—
A lofty peak of virtue and of peace
Art thou, O Jomeokee!

HER PRISON LIFE[12]


Her prison life was long and lone
Her kindred buried or unknown;
Of naught had she kept any score,
In truth her mind deprived of lore,
But knew her grief to be her own.

Another heart had better grown,


Confessing murder had he sown;
“I did the deed, and I deplore
Her prison life.”

But hope and heart and health had flown;


Why cares she now what winds are blown?
“I guess I’ll stay here as before,
My all is gone and evermore”—
Her living death, one long-drawn moan,
Her prison life.
Photograph of a rare old painting by
the Spanish artist, Herrera, and owned
by Dr. Andrew Anderson of St. Augustine,
Fla.
AURELIUS AUGUSTINUS
O thou, immortal father,
Permit my spirit poor to rise with thine.
Thou didst ascend, high Heaven’s hero,
From thy soft bed of prayer at Hippo,
Centuries agone,
Very Vandals storming thy gates the while.

Victor art thou still, and higher,


More mighty, honored more.
Amongst men thou didst eat
Of the tree of knowledge, good and evil—
How human as boy and man!
Yet thou didst name thy first born,
In youth begotten of thine unlawful union,
Adeodatus, “a gift from God.”
Again and again thou didst strike
For freedom from thy fetters and thy foes,
Till thou hadst conquered,
Later painting thy life of lust
In color like unto darkest night.

With hungry heart and spirit high,


Thou oft didst delve into Cicero’s Hortentius,
And give thy faith to Manichaeus,
Seeking to know evil and its source—
The ever pressing problem, eternally inscrutable.

After God all things good had made,


Yea very good,
A fearless fool hath said,
“He turned Himself into the tempting serpent—”
Shocking diabolism!
Creators two?
Incredible, impossible.
Then it follows,
One evil became.
But when and where; by whom and why?
With all this thou didst wrestle,
And more bitterly with thyself.

Yet thou didst give to God


And all the ages
Thy “Confession,” thine and mine;
Thy “De Natura et Gratia”—
The everlasting conflict;
Books fifteen on a single theme,
At once the highest and holiest,
The redeeming Trinity.
Many a tractate and treatise
Thou didst leave to men.
We bless thee for all this,
Thy holy heritage, O Augustine,
More brilliant than Ambrose,
Of truth more jealous than Jerome,
More profound than Gregory the Great;
The super-man of thy day and many,
Thou enthroned son of the Highest.

Beholding now thy form and face—


Master work of Herera’s hands,
Done a millennium after thy ascent,
A worshipful face toward the Holy Father’s,
With quill in thy skillful hand,
“The City of God”[13] before thee,
My soul astir doth soar
Toward thine and His.
Oft have I gazed and gloried,
Imaging thy topless, hallowed heights,
From deepest, darkest depths—
I too may rise; I will, O God, I will!

O THAT INCOME TAX!


I struggled with mine till the midnight hour;
My head was that of a fool;
My losses and gains, they’re beyond my power,
And never the like was, in school.

That minus sign was ever my foe


From earliest years until now;
My modest income, and varied out-go—
O they must be figured somehow!

I’ll tell you the truth, in the fear of the Lord,


I worried and went “sick abed;”
Six pages of puzzles and all a sworn word—
“O where,” I sighed, “is my head?”

“If married,” or “single”—I failed to know:


Nor dependent children could tell;
For never my mind received such a blow,
From such unexpected hell.

I always have cherished my Uncle Sam,


And thought he was oftenest right;
But flooded I was, nor a single dam
To check my downward flight.

Exhausted I slept, nor just or unjust,


Resolving the next day to seek aid;
For when I awoke ’twas still, “you must
Or penalty dire be paid.”

To the revenue clerk I took me straight,


And behold, as I looked, I heard
A lot of fond fools at Uncle Sam’s gate,
Despairing like a caged bird.

The officer smiled, and I smiled out loud,


For misery loves company;
And the smiles were like beams that broke the cloud
Of impending, rank perjury.

The blanks I filled in from A to O,


But omitted the “profits from sale”—
I once grew rich with a plow and hoe,
When a whistling boy and hale.

In those olden days no kind of a tax


For City or State revenue
Was imposed on boys except a few whacks,
But now they forever are due.

I swore and I signed and in full I paid


That puzzling tax return;
Once more I laughed, and again I said,
“’Tis always do, and you learn.”

And now it is done, and thoroughly done,


Halleluia, I’ll get there yet;
But by all that’s good and true ’neath the sun,
I swear that folly to forget.

IN FLORIDA
They come from everywhere,
By land, by sea and air,
The old, the young and fair—
And all without a care,
In Florida.

Just pause, my friend, and see


The multitudes that be
O’er lovely shore and lea;
They reach from sea to sea,
In Florida.

Look at the aged one,


Who shines like a little sun,
And feels himself undone,
If he played not golf and won,
In Florida.

His gouty feet must dance,


His eye will look askance,
And his mind make glad advance,
To reach five score, perchance,
In Florida.

Yes, let him have his wish


To feel the line’s quick swish,
And catch his finest fish
For his epicurean dish,
In Florida.

’Tis here he makes the stride;


There’s nothing he can’t ride,
With a maiden by his side—
Yet a few things must he hide,
In Florida.

The birds and trees here sing;


The prigs and plants upspring,
And each gets in the swing,
With Nature all a-wing,
In Florida.

Behold, my friend, the youth,


The forward, the uncouth;
The gentle and their ruth,
The beauty and the truth,
In Florida.

It’s like a moving stage,


The folk of every age;
No place nor cause for rage—
Even workless have their wage—
In Florida.

Then see the females all;


Alack! you rise or fall,
Or else your heart forestall,
In this moving, magic ball,
In Florida.

One great kaleidoscope,


From silk to dirt and dope,
From puppet to a pope,
This passing throng of hope,
In Florida.

TWO LITTLE ORPHANS


Two orphans in the world are left,
A brother and sister sighing;
Two Vireos aggrieved, bereft,
Two little orphans crying.

By the Author.

Close clinging to their cheerless nest,


Two little birds are trying
To call back joys of mother’s breast,
A mother, lifeless lying.

God’s two-fold plan for making song—


Some fiend the while defying—
And man’s two friends their whole life long;
Two little orphans crying.

No answer comes, save from the King,


A King who’s aye supplying
The needs of the great and smallest thing—
His little orphans crying.
By Courtesy of Briscoe and Arnold.

TROUBLE AND PLAY


It’s trouble and gladness from first to the last,
Ere joy is quite vanquished some sorrow comes fast;
Yet while old Calamity’s having his way,
For one that’s in trouble, there are others at play.

What is play to the pup is grief to the child;


What is fun for the boy makes mother go wild;
Some deeds of the mother cause angels to weep;
While God smiles over all, and all He doth keep.

SOME SMALL SURPRISES


We never foreknow, but our hearts were a-glow,
The hearts of Artena and I,
As we walked to and fro by the waters a-flow,
The waters in “the land of the sky.”

The children see true—they generally do—


The charming things all around;
I followed her view, and I presently knew
A Tanager’s nest was found.

The boys advanced, as soon as they glanced,


And down came the limb of a tree;
Thus fortune chanced, while little hearts danced,
With four wee fledglings to see.

With noisy protest, and tumult and zest,


The camera captured all four.
’Twas the parents’ sure test—they forsook the nest,
Though birdlings a-weeping sore!

I began to weep, in my heart quite deep,


When the babes kept up their cry;
I ran up the steep like a deer in a leap,
For the best bird food supply.

They reached and they tried; they ate and they cried,
Till the four had eaten their fill;
The mother aside still motherhood belied,
And the heart in me struggled still.

I learned in my youth, an old, new truth;


’Mongst men and beasts and birds,
Some grow uncouth, nor ever show ruth;
And for fools waste not your words.

Filled oft to the beak, as the days made a week,


The fledglings and I were friends,
And over the creek the folk came to speak
Of their beauty, their cuteness and ends.

And all the hearts right grew more tender and bright,
As the Tanagers grew apace;
And those of insight, said, “The birds have a right
To partake of our friendly grace.”

THE RHYTHM UNIVERSAL


Give me thy music, O most musical One,
The rhythm that rolls from yonder cycling sun;
Yea more, as heart and soul of all that’s good,
Thy nature gave in vaster plenitude;
Nor time will ever be when thy glad stars
Will cease to sing as one in rhythmic bars;
Nor conscious sons of God go shouting joy;
Nor woodland birds of song their loved employ.

It’s in the very heart of things;


It’s in our bounds and sweeps and swings;
It’s in the tree and rose that springs—
All Nature sings—— and—— sings.

The heart of man, his coursing blood through veins;


The very breath of life, his thoughts and reins;
His dreams, devotions, deeds, his all, O soul,
Or great or small beneath divine control.

The gracious seasons roll in mighty numbers;


The snow, the sleet but falls, that He who slumbers
Not may again awake the earth to life
And stay, for man and all, the winter’s strife.
The raging storm, the great earthquake and war
Are music bound, if we but see afar;
From heart of heav’n to heart of hell—ah yes;
The prince of darkness is beset, not less—
’Tis bars and feet, far-reaching leaps and falls,
Through light not seen in His momentous calls.

Consider Job—upright but proud—at last,


By grinding fate, by every woe held fast,
He turned to highest hills and King of all;
And never more asked he, “why such a fall?”
It was the rhythm of God through stops of sin;
’Twas His own anthems deep, without, within.

Our Pilgrim fathers, banished by the fates,


Brought out of many ills the United States;
And through each crisis great of all known time,
’Tis God in love; ’tis music full sublime.

At last the Lamb and Lion in song shall join;


The Child and Wolf eternal riches coin;
The Night shall sing to Day, and Day to Him,
Who receives the plaudits of the seraphim.

THE STONE CROSSES


AND THE FAIRIES
(In Patrick County, Virginia, little stone crosses have
been found and are yet obtainable. Jewelers of
Roanoke and Martinsville, Va., assure inquirers that the
Virginia “Fairy” or “Lucky” stones, discovered nowhere
else in the world, have been a puzzle to scientists, and
are being worn by some of the crowned heads of
Europe. A bulletin of the U. S. Geological Survey
speaks of them as “the most curious mineral found in
the United States,” and calls them Staurolite or Fairy
Stones.)

In Virginia’s historic hills around a hallowed spot,


There was born a mystic legend which ne’er shall be forgot;
A story true to Nature and to One without a blot—
The divinest story of old!

For glory bright is round it, which has softened many a heart,
A tale of wise and saintly ones, in universal art;
A story mightiest with men now and ever mighty part
It played in the races of old.

We yet believe that angels must have wept and good men sighed,
When Gallilee’s great Son with hateful spite was crucified;
But who would ever dream the fairy spirits were allied
In Heaven’s great scheme of old?

Yet when these blithesome fays were dancing by a mountain spring,


Ere the days of Pocahontas and Powhattan, the fearless King,
In union with the naiads, an elfin, swift of wing,
Came weeping from the East, of old.

The story sad he told of Christ, the Saviour, and His Cross;
Then joy and laughter sudden ceased, and grieving for their loss,
They shed their tears upon the pebbles and on the velvet moss—
A heaven moved grief of old.

And lo, when they had flown from the enchanted spring and ground,
Just where the tears had fallen on the pebbles lying round,
The Fairy stony crosses by the thousand there were found,
Sweet Nature’s crosses of old.
Note the crosses in this clod of earth.
Photographed in Patrick County, Va.

THE SUN FLOWER


’Tis the flower that looms and turns to pure gold,
Yes, the flower that loves, and is loved the best;
For it plans from the first—this is love’s true test—
To give forth its riches to young and to old.

It o’er reaches men high with its shining crest,


Yet never in climbing unduly bold—
’Tis the flower that looms and turns to pure gold,
Yes, the flower that loves, and is loved, the best.

The Gold Finches arrive as its petals unfold,


And the Cardinal’s joy is manifest,
As groom gives to bride the jolly behest
To feast on its wealth and in her heart to hold
The flower that looms and turns to pure gold,
Yes, the flower that loves, and is loved, the best.

COLONEL DIAMOND AND


GRAND-DAUGHTER
I would like to attain to my four score and two,
With a joy in my heart and with naught to efface,
Could I dance, or could sing with an energy true,
Could I lighten the load of the populace.
I’d run out in the open for Nature’s embrace,
With a mind ever high, yet my feet on the sod;
While my soul would be set to the music of grace,
With the heart of a child and the gifts of a god.
Photograph taken when he was
82 years of age.

My pursuit would be learning the old and the new;


And whenever I could I would Psyche’s wings chase!
I would speak of high art with my privileged few,
And persuade men below to the nobler race;
In the faith I’d rejoice that the world grows apace.
I would skip on the mountain, or valley’s dull clod,
Having plenty and power, or only an ace,
With the heart of a child and the gifts of a god.

I would rather, like Diamond, all the way through,


Either poor, or unknown, or with glorious mace,
Make somebody happy—ah, many and you!
And the love of a child with my love interlace;
Yes, content with my lot, and the righteous ukase.
I would work and I’d play, but never more plod;
A glad song in my heart, and a smile on my face,
With the heart of a child and the gifts of a god.

Envoy
Here’s to Diamond’s health, to the grand-daughter’s grace;
They are under love’s sway, which surpasses the rod;
So united and happy in every place,
With the heart of a child and the gifts of a god.

THE WILD WOOD


How wonderful the wild wood,
The fresh sweet wood with its hush.
Silent, my soul! Take thou the mood
Of Veery and of Thrush,
’Way out in the wild wood.

Give ear to hymn of oak and pine;


Drink, my soul, drink deep;
The master Muse would make it thine,
But who can fully know the sweep
Of music of the wild wood?

Each tree sings low an old, new song,


Softest lay of life and love;
Unmarred by the daring, prattling throng
Of rushing men—like a dove
My soul in the wild wood.

The honeysuckle and wild rose—


Purity and balm a-bloom—
Refresh my heart and they transpose
My hungry mind to richer room
And food in the wild wood.
The violets with their upward look,
The stones beneath my feet,
Make one and all an open book;
Ah, the meditations meet,
With God in the wild wood.

At length the sun puts on pure gold;


The birds and breezes softer sing,
List! all, within this shrine of old,
Chime symphonies to the King—
High mass in the wild wood!

THE BEGINNING OF THINGS


The beginning of things, the first of all men—
It fascinates me, and I’ve wondered when
Welcome to our website – the ideal destination for book lovers and
knowledge seekers. With a mission to inspire endlessly, we offer a
vast collection of books, ranging from classic literary works to
specialized publications, self-development books, and children's
literature. Each book is a new journey of discovery, expanding
knowledge and enriching the soul of the reade

Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.

Let us accompany you on the journey of exploring knowledge and


personal growth!

ebookgate.com

You might also like