当前位置: 100md首页 > 医学版 > 医学资料 > 资料下载2019
编号:8566
《英文原版》.PHP5.Advance-Visual.QuickPro.Guide.pdf
http://www.100md.com 2015年1月5日
《PHP 5 高级应用开发实践 (高清中文PDF版)》(About PHP 5 Advanced: Visual QuickPro Guid
第1页
第6页
第14页
第25页
第40页
第221页

    参见附件(11047KB,609页)。

     中文名: PHP 5 高级应用开发实践 (高清中文PDF版)

    原名: About PHP 5 Advanced: Visual QuickPro Guide, 2nd Edition

    别名: PHP5

    版本: ZIP

    发行时间: 2008年

    地区: 大陆

    语言: 简体中文

    PHP 5 高级应用开发实践 简介:

    PHP 5 高级应用开发实践 内容介绍:

    《PHP 5 高级应用开发实践》
PHP是目前开发动态Web站点最流行的语言,本书介绍了PHP高级编程技术及相关主题。全书划分为三个部分。前5章介绍一般的高级PHP知识:编程技巧、Web应用程序、数据库、安全和电子商务。接下来的6章内容着重扩展PHP的知识范围。

    《PHP 5 高级应用开发实践》其中一半的内容非常详细地复习了面向对象编程——从基础知识到高级主题再到一些实用范例。另外3章介绍使用PHP的不同方式:与网络服务程序通信、与主机服务程序通信、从命令行使用PHP。本书最后3章分别介绍与PHP相关的三种技术:PEAR、Ajax 和XML。

    《PHP 5 高级应用开发实践》本书针对PHP的中高级程序员,通过大量实用范例帮助读者迅速掌握高级技术。

    PHP 5 高级应用开发实践 作者简介:

    Larry UIIman是国际知名的畅销技术作家,拥有20多年编程经验,精通多种语言和技术。他是DMC公司的总裁和数字媒体技术总监,曾担任朗讯和OracIe 等世界顶尖公司的顾问,并曾授课于加州大学伯克利分校、宾州大学等名校。除本书外,他撰写的多部图书都广受世界读者欢迎,享有极高声誉。

    PHP 5 高级应用开发实践 目录:

    第1章 PHP高级技术

    1.1 多维数组

    1.1.1 多维数组排序

    1.1.2 数据库驱动的数组

    1.2 高级函数定义

    1.2.1 递归函数

    1.2.2 使用静态变量

    1.3 原形文档语法

    1.4 使用printf()和sprintf()

    第2章 开发Web应用程序

    2.1 注释代码

    2.2 代码风格和结构

    2.3 Web站点的模块化

    2.3.1 创建配置文件

    2.3.2 创建HTML模板

    2.3.3 创建索引页面

    2.3.4 创建内容模块

    2.3.5 创建搜索模块

    2.4 调整浏览器缓存

    第3章 数据库高级概念

    3.1 在数据库里保存会话

    3.1.1 创建sessions表

    3.1.2 定义会话函数

    3.1.3 使用新会话处理程序

    3.2 处理美国邮政编码

    3.2.1 创建邮政编码表

    3.2.2 创建stores表

    3.2.3 计算距离

    3.3 创建存储函数

    3.4 水平显示结果

    第4章 安全技术

    4.1 基础知识

    4.2 检验表单数据

    4.3 使用PECL过滤器

    4.4 利用PEAR Auth进行身份验证

    4.4.1 简单身份验证

    4.4.2 定制身份验证

    4.5 使用MCrypt

    4.5.1 数据加密

    4.5.2 数据解密

    第5章 电子商务技术

    5.1 电子商务的概念

    5.2 创建配置文件

    5.3 建立模板

    5.4 创建索引文件

    5.5 分类浏览

    5.6 展示产品

    5.7 实现购物车

    5.8 信用卡的检验

    第6章 面向对象编程基础知识

    6.1 面向对象编程的理论

    6.2 定义一个类

    6.3 创建对象

    6.4 $this属性

    6.5 创建构造器

    6.6 创建解构器

    6.7 自动加载类

    第7章 高级OOP

    第8章 实用面向对象编程

    第9章 PHP的网络应用

    第10章 PHP和服务器

    第11章 PHP的命令行界面

    第12章 使用PEAR

    第13章 Ajax

    第14章 XML和PHP

    PHP 5 高级应用开发实践

    VISUAL QUICKPRO GUIDE

    PHP 5 ADVANCED

    Larry Ullman

    Peachpit PressVisual QuickPro Guide

    PHP 5 Advanced

    Larry Ullman

    Peachpit Press

    1249 Eighth Street

    Berkeley, CA 94710

    510524-2178

    510524-2221 (fax)

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

    To report errors, please send a note to: errata@peachpit.com

    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 permissions@peachpit.com.

    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

    9 8 7 6 5 4 3 2 1

    Printed and bound in the United States of AmericaDedication

    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!Introduction ix

    Chapter 1: Advanced PHP Techniques 1

    Chapter 2: Developing Web Applications 43

    Chapter 3: Advanced Database Concepts 81

    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

    Contents at a Glance

    Contents at a Glancevi

    Introduction ix

    Chapter 1: Advanced PHP Techniques 1

    Multidimensional Arrays . . . . . 2

    Advanced Function Definitions . . . . 18

    The Heredoc Syntax . . . . . . 31

    Using printf and sprintf . . . . 37

    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

    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

    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

    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

    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

    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

    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 betterWeb 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

    i

    IntroductionAbout 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,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

    Introductionnetworked 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.comtitle0321376013

    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

    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

    IntroductionWhat’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.comphorum). A

    fair amount of material is therefore based

    upon frequently asked questions I see.

    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

    IntroductionAbout 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.

    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

    IntroductionWhat 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

    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

    IntroductionSupport 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

    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.comtitle

    0321376013 to learn how to register this

    book and access the chapters.

    xv

    Introduction

    IntroductionThis page intentionally left blank 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.

    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 printfsprintf family of functions.

    1

    Advanced

    PHP Techniques

    1

    Advanced PHP techniquesMultidimensional 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

    list, which can have limitless dimensions

    (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,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’));

    This is a simple two-dimensional array (an

    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.

    Figure 1.2 The multidimensional array

    sorted by numeric value (key1).

    Figure 1.1 One use of multidimensional

    arrays will be to create a nested to-do

    list.

    2

    Chapter 1

    Multidimensional ArraysFigure 1.4 An alphabetical sort on

    the example array using key2.

    Figure 1.3 By printing out the values

    of x[‘key1’] and y[‘key1’], one

    can see how the user-defined sorting

    function is invoked.

    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

    array). If you used uasort, the keys would

    be maintained, and if you used uksort, the

    sort would be based upon the keys.

    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.

    3

    Advanced PHP Techniques

    Multidimensional ArraysTo 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).

    
    DTD XHTML 1.0 TransitionalEN”

    “http:www.w3.orgTRxhtml1DTD

    xhtml1-transitional.dtd”>

    
    xhtml” xml:lang=”en” lang=”en”>

    

    
    content=”texthtml; charset=

    iso-8859-1” >

    Sorting Multidimensional<br/><br/>     Arrays<title><head><br/><br/>     <body><br/><br/>     <?php Script 1.1 - sort.php<br/><br/>     2. Define a multidimensional array.<br/><br/>     students = array (<br/><br/>     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));<br/><br/>     The outer array, students, has five ele-<br/><br/>     ments, each of which is also an array. The<br/><br/>     inner arrays use the student’s ID for the<br/><br/>     key (a made-up value) and store two<br/><br/>     pieces of data: the student’s name and<br/><br/>     their grade.<br/><br/>     continues on page 6<br/><br/>     4<br/><br/>     Chapter 1<br/><br/>     Multidimensional Arrays1 <!DOCTYPE html PUBLIC -W3CDTD XHTML 1.0 TransitionalEN<br/><br/>     2 http:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd><br/><br/>     3 <html xmlns=http:www.w3.org1999xhtml xml:lang=en lang=en><br/><br/>     4 <head><br/><br/>     5 <meta http-equiv=content-type content=texthtml; charset=iso-8859-1 ><br/><br/>     6 <title>Sorting Multidimensional Arrays<title><br/><br/>     7 <head><br/><br/>     8 <body><br/><br/>     9 <?php Script 1.1 - sort.php<br/><br/>     10<br/><br/>     11 This page creates a multidimensional array<br/><br/>     12 of names and grades.<br/><br/>     13 The array is then sorted twice:<br/><br/>     14 once by name and once by grade.<br/><br/>     15<br/><br/>     16<br/><br/>     17 Create the array:<br/><br/>     18 Array structure:<br/><br/>     19 studentID => array ('name' => 'Name', 'grade' => XX.X)<br/><br/>     20 students = array (<br/><br/>     21 256 => array ('name' => 'Jon', 'grade' => 98.5),22 2 => array ('name' => 'Vance', 'grade' => 85.1),23 9 => array ('name' => 'Stephen', 'grade' => 94.0),24 364 => array ('name' => 'Steve', 'grade' => 85.1),25 68 => array ('name' => 'Rob', 'grade' => 74.6)<br/><br/>     26 );<br/><br/>     27<br/><br/>     28 Name sorting function:<br/><br/>     29 function name_sort (x, y) {<br/><br/>     30 return strcasecmp(x['name'], y['name']);<br/><br/>     31 }<br/><br/>     32<br/><br/>     33 Grade sorting function:<br/><br/>     34 Sort in DESCENDING order!<br/><br/>     35 function grade_sort (x, y) {<br/><br/>     36 return (x['grade'] < y['grade']);<br/><br/>     37 }<br/><br/>     38<br/><br/>     39 Print the array as is:<br/><br/>     40 echo '<h3>Array As Is<h3><pre>' . print_r(students, 1) . '<pre>';<br/><br/>     41<br/><br/>     42 Sort by name:<br/><br/>     43 uasort (students, 'name_sort');<br/><br/>     44<br/><br/>     45 Print the array now:<br/><br/>     46 echo '<h3>Array Sorted By Name<h3><pre>' . print_r(students, 1) . '<pre>';<br/><br/>     47<br/><br/>     48 Sort by grade:<br/><br/>     49 uasort (students, 'grade_sort');<br/><br/>     50<br/><br/>     51 Print the array now:<br/><br/>     52 echo '<h3>Array Sorted By Grade<h3><pre>' . print_r(students, 1) . '<pre>';<br/><br/>     53<br/><br/>     54 ?><br/><br/>     55 <body><br/><br/>     56 <html><br/><br/>     Script 1.1 This script defines a two-dimensional array, which is then sorted based upon the inner array values.<br/><br/>     5<br/><br/>     Advanced PHP Techniques<br/><br/>     Multidimensional Arrays3. Define the name sorting function.<br/><br/>     function name_sort (x, y) {<br/><br/>     return strcasecmp(x[‘name’],? y[‘name’]);<br/><br/>     }<br/><br/>     The strcasecmp function returns a<br/><br/>     number—negative, 0, or positive—indi-<br/><br/>     cating how similar two strings are. If a<br/><br/>     negative value is returned, the first string<br/><br/>     comes before the second alphabetically; if<br/><br/>     a positive value is returned, the second<br/><br/>     string comes first. If 0 is returned, the<br/><br/>     strings are the same.<br/><br/>     4. Define the grade sorting function.<br/><br/>     function grade_sort (x, y) {<br/><br/>     return (x[‘grade’] <<br/><br/>     y[‘grade’]);<br/><br/>     }<br/><br/>     This example is like the demo in the<br/><br/>     introduction to these steps. One signifi-<br/><br/>     cant difference is that I want to perform<br/><br/>     a descending sort, so that the highest<br/><br/>     grades are listed first. This is easily<br/><br/>     accomplished: change the comparison<br/><br/>     operator from greater than to less than.<br/><br/>     5. Print the array as it’s initially defined.<br/><br/>     echo ‘<h3>Array As Is<h3><pre>’ .<br/><br/>     print_r(students, 1) . ‘<pre>’;<br/><br/>     For improved legibility, I’ll use the <pre><br/><br/>     tags and print_r to quickly reveal the<br/><br/>     arrays’ structure and values.<br/><br/>     6. Sort the array by name and print the<br/><br/>     results.<br/><br/>     uasort (students, ‘name_sort’);<br/><br/>     echo ‘<h3>Array Sorted By<br/><br/>     Name<h3><pre>’ .<br/><br/>     print_r(students, 1) . ‘<pre>’;<br/><br/>     Here the uasort function is used so<br/><br/>     that the keys—the student IDs—are not<br/><br/>     lost. Figure 1.5 shows the result if just<br/><br/>     usort was used instead.<br/><br/>     Figure 1.5 Failure to use uasort would<br/><br/>     cause the keys, which store meaningful<br/><br/>     values (see Script 1.1), to be lost.<br/><br/>     6<br/><br/>     Chapter 1<br/><br/>     Multidimensional ArraysFigure 1.6 The initial array and sorted<br/><br/>     by name.<br/><br/>     7. Sort the array by grade and print the<br/><br/>     results.<br/><br/>     uasort (students, ‘grade_sort’);<br/><br/>     echo ‘<h3>Array Sorted By<br/><br/>     Grade<h3><pre>’ .<br/><br/>     print_r(students, 1) . ‘<pre>’;<br/><br/>     7<br/><br/>     Advanced PHP Techniques<br/><br/>     Multidimensional Arrays<br/><br/>     8. Complete the page.<br/><br/>     ><body><html><br/><br/>     9. Save the file as sort.php, place it in your<br/><br/>     Web directory, and test in your Web<br/><br/>     browser (Figures 1.6 and 1.7).<br/><br/>     Figure 1.7 The array sorted by grade, in<br/><br/>     descending order (this is the same Web<br/><br/>     page as in Figure 1.6, but it couldn’t all<br/><br/>     fit in one screenshot).Database-driven arrays<br/><br/>     If you think about it, most database queries<br/><br/>     return a multidimensional array (Figure 1.8).<br/><br/>     If the query results are immediately sent to<br/><br/>     the Web browser one at a time, the multidi-<br/><br/>     mensional structure doesn’t add any compli-<br/><br/>     cation to your code. However, if you need to<br/><br/>     do something more elaborate with the results,you’ll need a way to comprehend and man-<br/><br/>     age the nested structure.<br/><br/>     For this example, I want to create a database-<br/><br/>     driven, Web-based to-do list system. If the<br/><br/>     to-do list were one-dimensional, this wouldn’t<br/><br/>     be that hard. But the list should be nestable,where each item can have multiple steps.<br/><br/>     The result will be a tree-like structure, where<br/><br/>     each branch can have its own offshoots<br/><br/>     (Figure 1.9).<br/><br/>     Figure 1.8 Selecting multiple columns from multiple<br/><br/>     rows in a database results in a multidimensional<br/><br/>     array.<br/><br/>     8<br/><br/>     Chapter 1<br/><br/>     Multidimensional Arrays<br/><br/>     Figure 1.9 How a nested to-do list looks as a tree.Figure 1.10 This table represents the same data as in<br/><br/>     Figures 1.8 and 1.9. There will be a pseudo–foreign<br/><br/>     key–primary key relationship between the task_id<br/><br/>     and parent_id columns.<br/><br/>     The database required by this is surprisingly<br/><br/>     simple (Table 1.1). The trick is that each item<br/><br/>     has a parent_id attribute. If an item is a sub-<br/><br/>     step, its parent_id would be the task number<br/><br/>     of the item that it falls under (Figure 1.10).<br/><br/>     If an item is not a substep, its parent_id<br/><br/>     would be 0. It’s a very simple setup, but han-<br/><br/>     dling this in PHP will take some effort.<br/><br/>     Over the next few pages, you’ll create the<br/><br/>     database table and a PHP script for adding<br/><br/>     new tasks. In the next sections of the chap-<br/><br/>     ter, you’ll see how to use recursive functions<br/><br/>     to handle the multidimensional array.<br/><br/>     9<br/><br/>     Advanced PHP Techniques<br/><br/>     Multidimensional Arrays<br/><br/>     Column Name Type Extra<br/><br/>     task_id INT UNSIGNED AUTO_INCREMENT, Primary Key<br/><br/>     parent_id INT UNSIGNED NOT NULL, DEFAULT 0<br/><br/>     task VARCHAR(100) NOT NULL<br/><br/>     date_added TIMESTAMP NOT NULL<br/><br/>     date_completed TIMESTAMP<br/><br/>     The tasks Table<br/><br/>     Table 1.1 This one database table is all that is required to manage a nested to-do list.To create the database:<br/><br/>     1. Access MySQL using the mysql client or<br/><br/>     other interface.<br/><br/>     I’ll be using MySQL in this example, but<br/><br/>     you can use any database application, of<br/><br/>     course. To create the table, I’ll use the<br/><br/>     command-line mysql client, but you could<br/><br/>     use phpMyAdmin or one of MySQL’s<br/><br/>     graphical interfaces instead.<br/><br/>     2. Select the test database (Figure 1.11).<br/><br/>     USE test;<br/><br/>     I’ll just throw this one table within the<br/><br/>     test database, as it’s not part of any<br/><br/>     larger application. You can put it in a<br/><br/>     different database, if you prefer.<br/><br/>     3. Create the table (Figure 1.12).<br/><br/>     CREATE TABLE tasks (<br/><br/>     task_id INT UNSIGNED NOT NULL<br/><br/>     AUTO_INCREMENT,parent_id INT UNSIGNED NOT NULL<br/><br/>     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));<br/><br/>     The task_id is an automatically incre-<br/><br/>     mented primary key. The value will also<br/><br/>     be used as the parent_id if a task is a sub-<br/><br/>     step. The task itself goes into a VAR-<br/><br/>     CHAR(100) column, which you could also<br/><br/>     define as a text type if you wanted to<br/><br/>     allow for longer descriptions. Two time-<br/><br/>     stamp columns round out the table, one<br/><br/>     documenting when the task was added<br/><br/>     and another to indicate its completion.<br/><br/>     Three standard indexes are placed on<br/><br/>     columns that might be used in queries.<br/><br/>     Figure 1.12 Creating the tasks table.<br/><br/>     Figure 1.11 The table will be created within the test<br/><br/>     database.<br/><br/>     10<br/><br/>     Chapter 1<br/><br/>     Multidimensional ArraysFigure 1.13 The tasks will normally be added using a<br/><br/>     PHP script, but a test insertion is run just to make<br/><br/>     sure everything is on the up and up.<br/><br/>     4. Test the table by adding a dummy task<br/><br/>     (Figure 1.13):<br/><br/>     INSERT INTO tasks (task) VALUES<br/><br/>     (‘Must Do This!’);<br/><br/>     SELECT FROM tasks;<br/><br/>     For a simple task that’s not a subset of<br/><br/>     another task, only the one column needs<br/><br/>     to be provided with a value. The SELECT<br/><br/>     query confirms that the parent_id,date_added, and date_completed columns<br/><br/>     are automatically given default values<br/><br/>     (0000-00-00 00:00:00 is the TIMESTAMP<br/><br/>     equivalent of 0).<br/><br/>     5. Empty the table.<br/><br/>     TRUNCATE tasks;<br/><br/>     11<br/><br/>     Advanced PHP Techniques<br/><br/>     Multidimensional ArraysTo add tasks to the database:<br/><br/>     1. Begin a new PHP script in your text edi-<br/><br/>     tor or IDE, starting with the HTML<br/><br/>     (Script 1.2).<br/><br/>     <!DOCTYPE html PUBLIC “-W3C<br/><br/>     DTD XHTML 1.0 TransitionalEN”<br/><br/>     “http:www.w3.orgTRxhtml1DTD<br/><br/>     xhtml1-transitional.dtd”><br/><br/>     <html xmlns=”http:www.w3.org1999<br/><br/>     xhtml” xml:lang=”en” lang=”en”><br/><br/>     1 <!DOCTYPE html PUBLIC -W3CDTD XHTML 1.0 TransitionalEN<br/><br/>     2 http:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd><br/><br/>     3 <html xmlns=http:www.w3.org1999xhtml xml:lang=en lang=en><br/><br/>     4 <head><br/><br/>     5 <meta http-equiv=content-type content=texthtml; charset=iso-8859-1 ><br/><br/>     6 <title>Add a Task<title><br/><br/>     7 <head><br/><br/>     8 <body><br/><br/>     9 <?php Script 1.2 - add_task.php<br/><br/>     10<br/><br/>     11 This page adds tasks to the tasks table.<br/><br/>     12 The page both displays and handles the form.<br/><br/>     13<br/><br/>     14<br/><br/>     15 Connect to the database:<br/><br/>     16 dbc = @mysqli_connect ('localhost', 'username', 'password', 'test') OR die ('<p>Could not<br/><br/>     connect to the database!<p><body><html>');<br/><br/>     17<br/><br/>     18 Check if the form has been submitted:<br/><br/>     19 if (isset(_POST['submitted']) !empty(_POST['task'])) {<br/><br/>     20<br/><br/>     21 Sanctify the input...<br/><br/>     22<br/><br/>     23 The parent_id must be an integer:<br/><br/>     24 if (isset(_POST['parent_id'])) {<br/><br/>     25 parent_id = (int) _POST['parent_id'];<br/><br/>     26 } else {<br/><br/>     27 parent_id = 0;<br/><br/>     28 }<br/><br/>     29<br/><br/>     30 Escape the task:<br/><br/>     31 Assumes Magic Quotes are off!<br/><br/>     32 task = mysqli_real_escape_string(dbc, _POST['task']);<br/><br/>     33<br/><br/>     34 Add the task to the database.<br/><br/>     35 q = INSERT INTO tasks (parent_id, task) VALUES (parent_id, 'task');<br/><br/>     36 r = mysqli_query(dbc, q);<br/><br/>     37<br/><br/>     38 Report on the results:<br/><br/>     39 if (mysqli_affected_rows(dbc) == 1) {<br/><br/>     Script 1.2 Tasks are added to the database using this script. Tasks can even be filed under other tasks using the<br/><br/>     drop-down menu.<br/><br/>     12<br/><br/>     Chapter 1<br/><br/>     Multidimensional Arrays<br/><br/>     <head><br/><br/>     <meta http-equiv=”content-type”<br/><br/>     content=”texthtml; charset=<br/><br/>     iso-8859-1” ><br/><br/>     <title>Add a Task<title><head><br/><br/>     <body><br/><br/>     <?php Script 1.2 - add_task.php<br/><br/>     continues on page 1440 echo '<p>The task has been added!<p>';<br/><br/>     41 } else {<br/><br/>     42 echo '<p>The task could not be added!<p>';<br/><br/>     43 }<br/><br/>     44<br/><br/>     45 } End of submission IF.<br/><br/>     46<br/><br/>     47 Display the form:<br/><br/>     48 echo '<form action=add_task.php method=post><br/><br/>     49 <fieldset><br/><br/>     50 <legend>Add a Task<legend><br/><br/>     51<br/><br/>     52 <p>Task: <input name=task type=text size=60 maxlength=100 ><p><br/><br/>     53<br/><br/>     54 <p>Parent Task: <select name=parent_id><option value=0>None<option><br/><br/>     55 ';<br/><br/>     56<br/><br/>     57 Retrieve all the uncompleted tasks:<br/><br/>     58 q = 'SELECT task_id, parent_id, task FROM tasks WHERE date_completed=0000-00-00 00:00:00<br/><br/>     ORDER BY date_added ASC';<br/><br/>     59 r = mysqli_query(dbc, q);<br/><br/>     60<br/><br/>     61 Also store the tasks in an array for use later:<br/><br/>     62 tasks = array;<br/><br/>     63<br/><br/>     64 while (list(task_id, parent_id, task) = mysqli_fetch_array(r, MYSQLI_NUM)) {<br/><br/>     65<br/><br/>     66 Add to the select menu:<br/><br/>     67 echo <option value=\task_id\>task<option>\n;<br/><br/>     68<br/><br/>     69 Add to the array:<br/><br/>     70 tasks[] = array('task_id' => task_id, 'parent_id' => parent_id, 'task' => task);<br/><br/>     71<br/><br/>     72 }<br/><br/>     73<br/><br/>     74 echo '<select><p><br/><br/>     75<br/><br/>     76 <input name=submitted type=hidden value=true ><br/><br/>     77 <input name=submit type=submit value=Add This Task ><br/><br/>     78<br/><br/>     79 <form><br/><br/>     80 <fieldset><br/><br/>     81 ';<br/><br/>     82<br/><br/>     83 Sort the tasks by parent_id:<br/><br/>     84 function parent_sort (x, y) {<br/><br/>     85 return (x['parent_id'] > y['parent_id']);<br/><br/>     86 }<br/><br/>     87 usort (tasks, 'parent_sort');<br/><br/>     88<br/><br/>     89 Display all the tasks:<br/><br/>     90 echo '<h3>Current To-Do List<h3><ul>';<br/><br/>     91 foreach (tasks as task) {<br/><br/>     92 echo <li>{task['task']}<li>\n;<br/><br/>     93 }<br/><br/>     94 echo '<ul>';<br/><br/>     95 ?><br/><br/>     96 <body><br/><br/>     97 <html><br/><br/>     Script 1.2 continued<br/><br/>     13<br/><br/>     Advanced PHP Techniques<br/><br/>     Multidimensional Arrays2. Connect to the database.<br/><br/>     dbc = @mysqli_connect (‘localhost’,? ‘username’, ‘password’, ‘test’) OR<br/><br/>     die (‘<p>Could not connect to the<br/><br/>     database!<p><body><html>’);<br/><br/>     I’ll be using MySQL and the Improved<br/><br/>     MySQL functions in this script. These are<br/><br/>     available as of PHP 5 and MySQL 4.1. If<br/><br/>     you are using older versions of either, you’ll<br/><br/>     need to change the code accordingly.<br/><br/>     If a database connection couldn’t be<br/><br/>     made, an error is printed and the script<br/><br/>     terminated (Figure 1.14).<br/><br/>     3. Check if the form has been submitted.<br/><br/>     if (isset(_POST[‘submitted’])<br/><br/>     !empty(_POST[‘task’])) {<br/><br/>     The form (Figure 1.15) has one main<br/><br/>     text box and a drop-down menu. To test<br/><br/>     for the form’s submission, the conditional<br/><br/>     checks that a hidden input named sub-<br/><br/>     mitted is set and that the text box<br/><br/>     (named task) isn’t empty.<br/><br/>     4. Ensure that the parent_id value is an<br/><br/>     integer.<br/><br/>     if (isset(_POST[‘parent_id’])) {<br/><br/>     parent_id = (int)<br/><br/>     _POST[‘parent_id’];<br/><br/>     } else {<br/><br/>     parent_id = 0;<br/><br/>     }<br/><br/>     The parent_id value is another task’s<br/><br/>     task_id. It will come from the drop-down<br/><br/>     menu, which means that it should be an<br/><br/>     integer. But one shouldn’t make assump-<br/><br/>     tions (because if someone hacked the<br/><br/>     form to send text as the parent_id, it<br/><br/>     would break the query), so this variable is<br/><br/>     typecast to an integer. If a valid value is<br/><br/>     submitted, this casting will have no effect.<br/><br/>     Any invalid values will be turned into 0.<br/><br/>     The same applies if the script does not<br/><br/>     receive a _POST[‘parent_id’] value.<br/><br/>     Figure 1.15 The HTML form for adding tasks.<br/><br/>     Figure 1.14 If a database connection cannot be made,this is the result.<br/><br/>     14<br/><br/>     Chapter 1<br/><br/>     Multidimensional Arrays8. Complete the submission conditional<br/><br/>     and start the form.<br/><br/>     } End of submission IF.<br/><br/>     echo ‘<form action=”add_task.php”<br/><br/>     method=”post”><br/><br/>     <fieldset><br/><br/>     <legend>Add a Task<legend><br/><br/>     <p>Task: <input name=”task” type=<br/><br/>     ”text” size=”60” maxlength=”100”<br/><br/>     ><p><br/><br/>     <p>Parent Task: <select name=<br/><br/>     ”parent_id”><option value=<br/><br/>     ”0”>None<option><br/><br/>     ‘;<br/><br/>     The form has one text input and one<br/><br/>     drop-down menu. The menu will be pop-<br/><br/>     ulated from the list of existing tasks. The<br/><br/>     first possible value will be 0, for tasks that<br/><br/>     are not subservient to other tasks.<br/><br/>     9. Retrieve all the uncompleted tasks.<br/><br/>     q = ‘SELECT task_id, parent_id, task<br/><br/>     FROM tasks WHERE its date_<br/><br/>     completed=”0000-00-00 00:00:00”<br/><br/>     ORDER BY date_added ASC’;<br/><br/>     r = mysqli_query(dbc, q);<br/><br/>     The query returns three pieces of infor-<br/><br/>     mation for every uncompleted task<br/><br/>     (once a task has been completed, its<br/><br/>     date_completed column would have a<br/><br/>     nonzero value). The task_id and the task<br/><br/>     itself will be used in the drop-down<br/><br/>     menu. The parent_id will be used later<br/><br/>     to nest the tasks.<br/><br/>     continues on next page<br/><br/>     15<br/><br/>     Advanced PHP Techniques<br/><br/>     Multidimensional Arrays<br/><br/>     5. Secure the task value.<br/><br/>     task =<br/><br/>     mysqli_real_escape_string(dbc,? _POST[‘task’]);<br/><br/>     The mysqli_real_escape_string func-<br/><br/>     tion will make whatever submitted task<br/><br/>     value safe to use in the query.<br/><br/>     6. Add the task to the database.<br/><br/>     q = “INSERT INTO tasks (parent_id,? task) VALUES (parent_id,? ‘task’)”;<br/><br/>     r = mysqli_query(dbc, q);<br/><br/>     This query differs from the test query<br/><br/>     run earlier in that it also populates the<br/><br/>     parent_id field in the table.<br/><br/>     7. Report on the query results.<br/><br/>     if (mysqli_affected_rows(dbc) == 1)<br/><br/>     {<br/><br/>     echo ‘<p>The task has been<br/><br/>     added!<p>’;<br/><br/>     } else {<br/><br/>     echo ‘<p>The task could not be<br/><br/>     added!<p>’;<br/><br/>     }10. Create an array for storing the tasks.<br/><br/>     tasks = array;<br/><br/>     This script will list all the tasks twice:<br/><br/>     once in the drop-down menu and once<br/><br/>     after the form (Figure 1.16). This array<br/><br/>     will store the second list.<br/><br/>     11. Retrieve a database record and use it<br/><br/>     accordingly.<br/><br/>     while (list(task_id, parent_id,? task) = mysqli_fetch_<br/><br/>     array(r, MYSQLI_NUM)) {<br/><br/>     echo “<option value= ? ”task_id\”>task<option>\n”;<br/><br/>     tasks[] = array(‘task_id’ =><br/><br/>     task_id, ‘parent_id’ =><br/><br/>     parent_id, ‘task’ => task);<br/><br/>     }<br/><br/>     Within the while loop the retrieved<br/><br/>     record is used to populate the drop-<br/><br/>     down menu (Figure 1.17) and is also<br/><br/>     stored in the tasks array. This array will<br/><br/>     be multidimensional.<br/><br/>     12. Complete the form.<br/><br/>     echo ‘<select><p><br/><br/>     <input name=”submitted” type=<br/><br/>     ”hidden” value=”true” ><br/><br/>     <input name=”submit” type=”submit”<br/><br/>     value=”Add This Task” ><form><fieldset><br/><br/>     ‘;<br/><br/>     The hidden input here is a trick I use<br/><br/>     to check for a form’s submission. Doing<br/><br/>     this is sometimes necessary as just<br/><br/>     pressing Enter within Internet Explorer<br/><br/>     for Windows will submit a form without<br/><br/>     ever setting the _POST[‘submit’]<br/><br/>     variable.<br/><br/>     Figure 1.17 The PHP-generated HTML source code for<br/><br/>     the drop-down menu.<br/><br/>     Figure 1.16 The page contains the list of tasks two<br/><br/>     times.<br/><br/>     16<br/><br/>     Chapter 1<br/><br/>     Multidimensional ArraysFigure 1.19 Adding a task that’s a subset of an<br/><br/>     existing task.<br/><br/>     Figure 1.18 Adding a new task that’s not linked to<br/><br/>     another task.<br/><br/>     13. Sort the tasks by parent_id.<br/><br/>     function parent_sort (x, y) {<br/><br/>     return (x[‘parent_id’] ><br/><br/>     y[‘parent_id’]);<br/><br/>     }<br/><br/>     usort (tasks, ‘parent_sort’);<br/><br/>     The parent_id value is what separates<br/><br/>     primary tasks from secondary ones,so working with this value in PHP is<br/><br/>     important. Using the information dis-<br/><br/>     cussed earlier in the chapter, a user-<br/><br/>     defined function will sort the multidimen-<br/><br/>     sional array.<br/><br/>     14. Display the full list of tasks.<br/><br/>     echo ‘<h3>Current To-Do<br/><br/>     List<h3><ul>’;<br/><br/>     foreach (tasks as task) {<br/><br/>     echo “<li>{task[‘task’]}<br/><br/>     <li>\n”;<br/><br/>     }<br/><br/>     echo ‘<ul>’;<br/><br/>     This loop will display each task in order<br/><br/>     of its parent_id. This is the first step<br/><br/>     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.<br/><br/>     This will be solved later in the chapter.<br/><br/>     15. Complete the page.<br/><br/>     ><body><html><br/><br/>     16. Save the file as add_task.php, place it in<br/><br/>     your Web directory, and test in your Web<br/><br/>     browser (Figures 1.18 and 1.19).<br/><br/>     Tip<br/><br/>     ■ If you wanted to implement this idea in a<br/><br/>     live site, one improvement you could<br/><br/>     make would be the ability to add multi-<br/><br/>     ple tasks at once. I’ll provide further tips<br/><br/>     on fleshing out this example over the<br/><br/>     course of the chapter.<br/><br/>     17<br/><br/>     Advanced PHP Techniques<br/><br/>     Multidimensional ArraysAdvanced Function<br/><br/>     Definitions<br/><br/>     Being able to define and use your own func-<br/><br/>     tions is integral to any programming lan-<br/><br/>     guage. After even a modicum of PHP experi-<br/><br/>     ence, you’ve no doubt created many. But<br/><br/>     there are three potential features of user-<br/><br/>     defined functions that arise in more<br/><br/>     advanced programming. These are:<br/><br/>     ◆ Recursive functions<br/><br/>     ◆ Static variables<br/><br/>     ◆ Accepting values by reference<br/><br/>     While not often used, sometimes these con-<br/><br/>     cepts are indispensable. In discussing and<br/><br/>     demonstrating these first two concepts, I’ll<br/><br/>     continue to build upon the tasks example<br/><br/>     just begun in the chapter.<br/><br/>     Recursive functions<br/><br/>     Recursion is the act of a function calling<br/><br/>     itself.<br/><br/>     function somefunction {<br/><br/>     Some code.<br/><br/>     somefunction;<br/><br/>     Possible other code.<br/><br/>     }<br/><br/>     The end result is that your functions can act<br/><br/>     both as originally intended and as a loop.<br/><br/>     The one huge warning when using this tech-<br/><br/>     nique is to make sure your function has an<br/><br/>     “out” clause. For example, the following code<br/><br/>     will run ad infinitum:<br/><br/>     function add_one (n) {<br/><br/>     n++;<br/><br/>     add_one (n);<br/><br/>     }<br/><br/>     add_one (1);<br/><br/>     18<br/><br/>     Chapter 1<br/><br/>     Advanced Function Definitions<br/><br/>     The lack of a condition that determines<br/><br/>     when to stop execution of the function cre-<br/><br/>     ates a big programming no-no, the infinite<br/><br/>     loop. Compare that function to this one:<br/><br/>     function count_to_100 (n) {<br/><br/>     if (n <= 100) {<br/><br/>     echo n . '<br >';<br/><br/>     n++;<br/><br/>     count_to_100 (n);<br/><br/>     }<br/><br/>     }<br/><br/>     count_to_100 (1);<br/><br/>     This function will continue to call itself until<br/><br/>     n is greater than 100, at which point it will<br/><br/>     stop executing the function. (That’s obvi-<br/><br/>     ously a trivial use of this concept; a loop<br/><br/>     would do the same thing.)<br/><br/>     Recursive functions are necessary when you<br/><br/>     have a process that may be followed to an<br/><br/>     unknown depth. For example, a script that<br/><br/>     searches through a directory may have to<br/><br/>     search through any number of subdirecto-<br/><br/>     ries. Or an array might have an unknown<br/><br/>     number of dimensions....<br/><br/>     With the tasks table created earlier in the<br/><br/>     chapter, retrieving and displaying all the<br/><br/>     tasks is not hard (see Figures 1.17 and 1.18).<br/><br/>     However, the method used in add_task.php<br/><br/>     (Script 1.2) does not properly nest the tasks<br/><br/>     like that in Figure 1.1. To accomplish that<br/><br/>     desired end, a multidimensional array and a<br/><br/>     recursive function are required.1 <!DOCTYPE html PUBLIC -W3CDTD XHTML 1.0 TransitionalEN<br/><br/>     2 http:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd><br/><br/>     3 <html xmlns=http:www.w3.org1999xhtml xml:lang=en lang=en><br/><br/>     4 <head><br/><br/>     5 <meta http-equiv=content-type content=texthtml; charset=iso-8859-1 ><br/><br/>     6 <title>View Tasks<title><br/><br/>     7 <head><br/><br/>     8 <body><br/><br/>     9 <h3>Current To-Do List<h3><br/><br/>     10 <?php Script 1.3 - view_tasks.php<br/><br/>     11<br/><br/>     12 This page shows all existing tasks.<br/><br/>     13 A recursive function is used to show the<br/><br/>     14 tasks as nested lists, as applicable.<br/><br/>     15<br/><br/>     16<br/><br/>     17 Function for displaying a list.<br/><br/>     18 Receives one argument: an array.<br/><br/>     19 function make_list (parent) {<br/><br/>     20<br/><br/>     21 Need the main tasks array:<br/><br/>     22 global tasks;<br/><br/>     23<br/><br/>     24 Start an ordered list:<br/><br/>     25 echo '<ol>';<br/><br/>     26<br/><br/>     27 Loop through each subarray:<br/><br/>     28 foreach (parent as task_id => todo) {<br/><br/>     29<br/><br/>     (script continues on next page)<br/><br/>     Script 1.3 One recursive function and a potentially bottomless multidimensional array will properly display the<br/><br/>     nested list of tasks.<br/><br/>     <head><br/><br/>     <meta http-equiv=”content-type”<br/><br/>     content=”texthtml; charset=<br/><br/>     iso-8859-1” ><br/><br/>     <title>View Tasks<title><head><br/><br/>     <body><br/><br/>     <h3>Current To-Do List<h3><br/><br/>     <?php Script 1.3 - view_tasks.php<br/><br/>     continues on page 21<br/><br/>     19<br/><br/>     Advanced PHP Techniques<br/><br/>     Advanced Function Definitions<br/><br/>     To use recursion:<br/><br/>     1. Begin a new PHP script in your text edi-<br/><br/>     tor or IDE, starting with the HTML<br/><br/>     (Script 1.3).<br/><br/>     <!DOCTYPE html PUBLIC “-W3C<br/><br/>     DTD XHTML 1.0 TransitionalEN”<br/><br/>     “http:www.w3.orgTRxhtml1DTD<br/><br/>     xhtml1-transitional.dtd”><br/><br/>     <html xmlns=”http:www.w3.org1999<br/><br/>     xhtml” xml:lang=”en” lang=”en”>20<br/><br/>     Chapter 1<br/><br/>     Advanced Function Definitions<br/><br/>     30 Display the item:<br/><br/>     31 echo <li>todo;<br/><br/>     32<br/><br/>     33 Check for subtasks:<br/><br/>     34 if (isset(tasks[task_id])) {<br/><br/>     35<br/><br/>     36 Call this function:<br/><br/>     37 make_list(tasks[task_id]);<br/><br/>     38<br/><br/>     39 }<br/><br/>     40<br/><br/>     41 Complete the list item:<br/><br/>     42 echo '<li>';<br/><br/>     43<br/><br/>     44 } End of FOREACH loop.<br/><br/>     45<br/><br/>     46 Close the ordered list:<br/><br/>     47 echo '<ol>';<br/><br/>     48<br/><br/>     49 } End of make_list function.<br/><br/>     50<br/><br/>     51<br/><br/>     52 Connect to the database:<br/><br/>     53 dbc = @mysqli_connect ('localhost', 'username', 'password', 'test') OR die ('<p>Could not<br/><br/>     connect to the database!<p><body><html>');<br/><br/>     54<br/><br/>     55 Retrieve all the uncompleted tasks:<br/><br/>     56 q = 'SELECT task_id, parent_id, task FROM tasks WHERE date_completed=0000-00-00 00:00:00<br/><br/>     ORDER BY parent_id, date_added ASC';<br/><br/>     57 r = mysqli_query(dbc, q);<br/><br/>     58<br/><br/>     59 Initialize the storage array:<br/><br/>     60 tasks = array;<br/><br/>     61<br/><br/>     62 while (list(task_id, parent_id, task) = mysqli_fetch_array(r, MYSQLI_NUM)) {<br/><br/>     63<br/><br/>     64 Add to the array:<br/><br/>     65 tasks[parent_id][task_id] = task;<br/><br/>     66<br/><br/>     67 }<br/><br/>     68<br/><br/>     69 For debugging:<br/><br/>     70 echo '<pre>' . print_r(tasks,1) . '<pre>';<br/><br/>     71<br/><br/>     72 Send the first array element<br/><br/>     73 to the make_list function:<br/><br/>     74 make_list(tasks[0]);<br/><br/>     75<br/><br/>     76 ?><br/><br/>     77 <body><br/><br/>     78 <html><br/><br/>     Script 1.3 continued2. Begin defining a function.<br/><br/>     function make_list (parent) {<br/><br/>     global tasks;<br/><br/>     echo ‘<ol>’;<br/><br/>     The purpose of the function will be<br/><br/>     to display an array of items in an<br/><br/>     ordered list:<br/><br/>     <ol><br/><br/>     <li>Item 1<li><br/><br/>     <li>Item 2<li><br/><br/>     <li>Item 3<li><ol><br/><br/>     This function will take one argument,which will always be an array. Within the<br/><br/>     function, the tasks array (the main<br/><br/>     array) needs to be available—you’ll soon<br/><br/>     see why. Then the ordered list is begun.<br/><br/>     3. Loop through the array, printing<br/><br/>     each item.<br/><br/>     foreach (parent as task_id<br/><br/>     => todo) {<br/><br/>     echo “<li>todo”;<br/><br/>     A foreach loop will go through the array,printing each item within <li> tags.<br/><br/>     Those are begun here.<br/><br/>     continues on next page<br/><br/>     21<br/><br/>     Advanced PHP Techniques<br/><br/>     Advanced Function Definitions4. Check if any subtasks exist.<br/><br/>     if (isset(tasks[task_id])) {<br/><br/>     make_list(tasks[task_id]);<br/><br/>     }<br/><br/>     This is the most important part of the<br/><br/>     script. The tasks retrieved from the data-<br/><br/>     base will be tossed into a multidimen-<br/><br/>     sional array like that in Figure 1.20. For<br/><br/>     the main array, each key is a parent_id<br/><br/>     and the elements are arrays of tasks that<br/><br/>     fall under that parent_id. So after print-<br/><br/>     ing the initial <li> task, the function<br/><br/>     needs to check if this task has any sub-<br/><br/>     tasks; in other words: is there an array<br/><br/>     element in tasks whose key is this task<br/><br/>     ID? If so, then this function should be<br/><br/>     called again, sending that other part of<br/><br/>     the array (the element whose key is this<br/><br/>     task_id and whose value is an array of<br/><br/>     subtasks) as the argument. That will<br/><br/>     result in the code:<br/><br/>     <ol><br/><br/>     <li>Item 1<li><br/><br/>     <li>Item 2<br/><br/>     <ol><br/><br/>     <li>Subitem 1<li><br/><br/>     <li>Subitem 2<li><ol><li><br/><br/>     <li>Item 3<li><ol><br/><br/>     5. Complete the foreach loop and the<br/><br/>     function.<br/><br/>     echo ‘<li>’;<br/><br/>     } End of FOREACH loop.<br/><br/>     echo ‘<ol>’;<br/><br/>     } End of make_list function.<br/><br/>     Figure 1.20 The PHP script takes the tasks<br/><br/>     from the database and creates this<br/><br/>     multidimensional array.<br/><br/>     22<br/><br/>     Chapter 1<br/><br/>     Advanced Function DefinitionsThe tasks array will store every task.<br/><br/>     Figure 1.20 shows the final structure. As<br/><br/>     described in Step 4, the array’s outer-<br/><br/>     most key is the parent_id value from<br/><br/>     the table. The value of this outermost<br/><br/>     array is an array of the tasks with that<br/><br/>     parent_id.<br/><br/>     9. Add a debugging line, if desired.<br/><br/>     echo ‘<pre>’ . print_r(tasks,1) .<br/><br/>     ‘<pre>’;<br/><br/>     When dealing with multidimensional<br/><br/>     arrays, it’s vitally important to know and<br/><br/>     understand the structure you’re working<br/><br/>     with. When you uncomment this line (by<br/><br/>     removing the two slashes), the script will<br/><br/>     print the array like you see in Figure 1.20.<br/><br/>     10. Call the make_list function, sending it<br/><br/>     the array of top-level tasks.<br/><br/>     make_list(tasks[0]);<br/><br/>     Although the tasks variable is a multi-<br/><br/>     dimensional array, the make_list func-<br/><br/>     tion needs to be called only once, send-<br/><br/>     ing it the first array element. This ele-<br/><br/>     ment’s value is an array of tasks whose<br/><br/>     parent_id is 0. Within the function, for<br/><br/>     each of these tasks, a check will see if<br/><br/>     there are subtasks. So the function will<br/><br/>     end up accessing every task thanks to its<br/><br/>     recursive nature.<br/><br/>     11. Complete the page.<br/><br/>     ><body><html><br/><br/>     continues on next page<br/><br/>     23<br/><br/>     Advanced PHP Techniques<br/><br/>     Advanced Function Definitions<br/><br/>     6. Connect to the database.<br/><br/>     dbc = @mysqli_connect (‘localhost’,? ‘username’, ‘password’, ‘test’) OR<br/><br/>     die (‘<p>Could not connect to the<br/><br/>     database!<p><body><html>’);<br/><br/>     With the recursive function defined, the<br/><br/>     rest of the script needs to retrieve all the<br/><br/>     tasks, organize them in an array, and then<br/><br/>     call the make_list function.<br/><br/>     7. Define and execute the query.<br/><br/>     q = ‘SELECT task_id, parent_id, task<br/><br/>     FROM tasks WHERE<br/><br/>     date_completed=”0000-00-00 00:00:00”<br/><br/>     ORDER BY parent_id, date_added<br/><br/>     ASC’;<br/><br/>     r = mysqli_query(dbc, q);<br/><br/>     The query retrieves three pieces of infor-<br/><br/>     mation for each task: its ID, its parent_id,and the task itself. The conditional<br/><br/>     means that only noncompleted tasks are<br/><br/>     selected. The results are also ordered by<br/><br/>     the parent_id, so that every top-level task<br/><br/>     (with a parent_id of 0) is returned first. A<br/><br/>     secondary ordering by the date_added<br/><br/>     returns the tasks in the order they were<br/><br/>     added (an assumption being that’s how<br/><br/>     they are prioritized).<br/><br/>     8. Add each task to an array.<br/><br/>     tasks = array;<br/><br/>     while (list(task_id, parent_id,? task) = mysqli_fetch_<br/><br/>     array(r, MYSQLI_NUM)) {<br/><br/>     tasks[parent_id][task_id]<br/><br/>     = task;<br/><br/>     }Figure 1.22 There is no limit to the number of<br/><br/>     subtasks that this system supports.<br/><br/>     Figure 1.21 The page of tasks, as a bunch of<br/><br/>     nested lists.<br/><br/>     12. Save the file as view_tasks.php, place it<br/><br/>     in your Web directory, and test in your<br/><br/>     Web browser (Figure 1.21).<br/><br/>     13. Add some more subtasks and retest in<br/><br/>     your Web browser (Figure 1.22).<br/><br/>     Tips<br/><br/>     ■ The PHP manual suggests that you<br/><br/>     should avoid any recursive function that<br/><br/>     may call itself over 100 to 200 times.<br/><br/>     Doing so could crash the script or the<br/><br/>     Web server.<br/><br/>     ■ This page does assume that some tasks<br/><br/>     were returned by the database. You may<br/><br/>     want to add a conditional checking that<br/><br/>     tasks isn’t empty prior to calling the<br/><br/>     make_list function.<br/><br/>     24<br/><br/>     Chapter 1<br/><br/>     Advanced Function DefinitionsUsing static variables<br/><br/>     When working with recursion or, in fact,any script in which the same function may<br/><br/>     be called multiple times, you might want to<br/><br/>     consider using the static statement. static<br/><br/>     forces the function to remember the value of<br/><br/>     a variable from function call to function call,without using global variables. The example<br/><br/>     count_to_100 function (see the preceding<br/><br/>     section of this chapter) could be rewritten<br/><br/>     like so with the same result:<br/><br/>     function count_to_100 {<br/><br/>     static n = 1;<br/><br/>     if (n <= 100) {<br/><br/>     echo n . '<br >';<br/><br/>     n++;<br/><br/>     count_to_100 ;<br/><br/>     }<br/><br/>     }<br/><br/>     count_to_100 ;<br/><br/>     Of course, that’s not a very useful implemen-<br/><br/>     tation of the concept. The very astute reader<br/><br/>     may have wondered how I achieved the result<br/><br/>     in Figure 1.3. Showing the values being com-<br/><br/>     pared is not hard, but counting the iterations<br/><br/>     requires the use of static. Toward this end,sort.php will be modified.<br/><br/>     25<br/><br/>     Advanced PHP Techniques<br/><br/>     Advanced Function Definitions<br/><br/>     Completing This Example<br/><br/>     This example was primarily written to<br/><br/>     demonstrate multidimensional arrays and<br/><br/>     recursive functions. Still, it’s a nice exam-<br/><br/>     ple and worth implementing in a live site<br/><br/>     (the ability to nest tasks is great). If you<br/><br/>     wanted to do so, one feature you’d likely<br/><br/>     need is the ability to mark a task as com-<br/><br/>     pleted. An example later in the chapter<br/><br/>     will do just that. Another alteration would<br/><br/>     be to change the add_task.php page so<br/><br/>     that the drop-down menu reflects the<br/><br/>     hierarchy as well.<br/><br/>     Another likely addition would be the<br/><br/>     ability to add multiple tasks at once. And<br/><br/>     you may want to consider an edit task<br/><br/>     option. While you’re at it, the view tasks<br/><br/>     page could have a link that passes a<br/><br/>     value in the URL indicating whether all<br/><br/>     tasks should be displayed or just uncom-<br/><br/>     pleted ones. These are just some ideas.<br/><br/>     Turn to the book’s supporting forum<br/><br/>     (www.dmcinsights.comphorum) for<br/><br/>     assistance and more!To use static variables:<br/><br/>     1. Open sort.php (Script 1.1) in your text<br/><br/>     editor or IDE.<br/><br/>     2. Modify the name_sort function to read<br/><br/>     (Script 1.4):<br/><br/>     function name_sort (x, y) {<br/><br/>     static count = 1;<br/><br/>     echo “<p>Iteration count:<br/><br/>     {x[‘name’]} vs. {y[‘name’]}<br/><br/>     <p>\n”;<br/><br/>     count++;<br/><br/>     return strcasecmp(x[‘name’],? y[‘name’]);<br/><br/>     1 <!DOCTYPE html PUBLIC -W3CDTD XHTML 1.0 TransitionalEN<br/><br/>     2 http:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd><br/><br/>     3 <html xmlns=http:www.w3.org1999xhtml xml:lang=en lang=en><br/><br/>     4 <head><br/><br/>     5 <meta http-equiv=content-type content=texthtml; charset=iso-8859-1 ><br/><br/>     6 <title>Sorting Multidimensional Arrays<title><br/><br/>     7 <head><br/><br/>     8 <body><br/><br/>     9 <?php Script 1.4 - sort2.php<br/><br/>     10<br/><br/>     11 This page creates a multidimensional array<br/><br/>     12 of names and grades.<br/><br/>     13 The array is then sorted twice:<br/><br/>     14 once by name and once by grade.<br/><br/>     15 A static variable has been added to both<br/><br/>     16 functions to see how many times they are called.<br/><br/>     17<br/><br/>     18<br/><br/>     19 Create the array:<br/><br/>     20 Array structure:<br/><br/>     21 studentID => array ('name' => 'Name', 'grade' => XX.X)<br/><br/>     22 students = array (<br/><br/>     23 256 => array ('name' => 'Jon', 'grade' => 98.5),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.<br/><br/>     26<br/><br/>     Chapter 1<br/><br/>     Advanced Function Definitions<br/><br/>     Three lines of code have been added to<br/><br/>     the function. The first is the declaration<br/><br/>     of a static variable called count. It’s ini-<br/><br/>     tially set to 1, but that assignment only<br/><br/>     applies the first time this function is<br/><br/>     called (because it’s a static variable).<br/><br/>     Then the iteration number is printed<br/><br/>     (how many times this function has<br/><br/>     been called), along with the values being<br/><br/>     compared. Finally, the count variable is<br/><br/>     incremented.<br/><br/>     continues on page 2824 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)<br/><br/>     28 );<br/><br/>     29<br/><br/>     30 Name sorting function:<br/><br/>     31 function name_sort (x, y) {<br/><br/>     32 static count = 1;<br/><br/>     33 echo <p>Iteration count: {x['name']} vs. {y['name']}<p>\n;<br/><br/>     34 count++;<br/><br/>     35 return strcasecmp(x['name'], y['name']);<br/><br/>     36 }<br/><br/>     37<br/><br/>     38 Grade sorting function:<br/><br/>     39 Sort in DESCENDING order!<br/><br/>     40 function grade_sort (x, y) {<br/><br/>     41 static count = 1;<br/><br/>     42 echo <p>Iteration count: {x['grade']} vs. {y['grade']}<p>\n;<br/><br/>     43 count++;<br/><br/>     44 return (x['grade'] < y['grade']);<br/><br/>     45 }<br/><br/>     46<br/><br/>     47 Print the array as is:<br/><br/>     48 echo '<h3>Array As Is<h3><pre>' . print_r(students, 1) . '<pre>';<br/><br/>     49<br/><br/>     50 Sort by name:<br/><br/>     51 uasort (students, 'name_sort');<br/><br/>     52<br/><br/>     53 Print the array now:<br/><br/>     54 echo '<h3>Array Sorted By Name<h3><pre>' . print_r(students, 1) . '<pre>';<br/><br/>     55<br/><br/>     56 Sort by grade:<br/><br/>     57 uasort (students, 'grade_sort');<br/><br/>     58<br/><br/>     59 Print the array now:<br/><br/>     60 echo '<h3>Array Sorted By Grade<h3><pre>' . print_r(students, 1) . '<pre>';<br/><br/>     61<br/><br/>     62 ?><br/><br/>     63 <body><br/><br/>     64 <html><br/><br/>     Script 1.4 continued<br/><br/>     27<br/><br/>     Advanced PHP Techniques<br/><br/>     Advanced Function Definitions3. Modify the grade_sort function<br/><br/>     to read:<br/><br/>     function grade_sort (x, y) {<br/><br/>     static count = 1;<br/><br/>     echo “<p>Iteration count:<br/><br/>     {x[‘grade’]} vs.<br/><br/>     {y[‘grade’]}<p>\n”;<br/><br/>     count++;<br/><br/>     return (x[‘grade’] <<br/><br/>     y[‘grade’]);<br/><br/>     }<br/><br/>     The same three lines of code that were<br/><br/>     added to name_sort are added to<br/><br/>     grade_sort, except the key being<br/><br/>     compared here is grade, not name.<br/><br/>     4. Save the file as sort2.php, place it in your<br/><br/>     Web directory, and test in your Web<br/><br/>     browser (Figur ......</div> <!--DuYiHuaAdd EndContent--></div> <div id="txtThisUrl"><br/>    <a href="http://www.100md.com/html/file/201501/058566.htm" target="_blank">http://www.100md.com/html/file/201501/058566.htm</a></div> <div id="txttips"><br/>您现在查看是摘要介绍页,<a href="http://www.100md.com/about/help.htm"> 详见PDF附件(11047KB,609页)</a>。</div> <script language="javascript" type="text/javascript" src="http://www.100md.com/comm/v2019/login.js"></script> <script language="javascript" type="text/javascript" src="http://www.100md.com/comm/v2019/after.js"></script> <div id="theRInfo"><script language="javascript" type="text/javascript" src="http://www.100md.com/rjs/file/201501/058566.js"></script><script language="javascript" type="text/javascript" src="http://www.100md.com/comm/v2019/related.js"></script></div> </div><div id="right"><script language="javascript" type="text/javascript" src="http://www.100md.com/comm/v2019/right.js"></script></div> </div><div id="copyright"><script language="javascript" type="text/javascript" src="http://www.100md.com/comm/v2019/copyright.js"></script></div></body></html>