1. Trang chủ
  2. » Công Nghệ Thông Tin

Tài liệu The Object Oriented Evolution of PHP5 ppt

67 985 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề The Object Oriented Evolution of PHP5
Tác giả Zeev Suraski
Người hướng dẫn Brian Jones, Editor-in-Chief
Trường học php|architect
Chuyên ngành Enterprise Applications
Thể loại magazine article
Năm xuất bản 2003
Thành phố not specified
Định dạng
Số trang 67
Dung lượng 1,68 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

On the one hand, everyone has direct access to the source code; no need to compile for separate platforms and distribute separate versions of your application.. But there is a clear dist

Trang 1

FEBRUARY 2003

VOLUME II - ISSUE 2

The Object Oriented

The Object Oriented

Evolution of PHP5

A Look At The New OOP Model

Using The Zend Engine 2.0

Tips&Tricks, Book Reviews, Product Reviews

and much more

Creating A Customized

Template-Engine

Hacking the Smarty

Template Engine

Data Fingerprinting with Hash Functions in PHP

Time Travel: Breadcrumbs and Session History with PHP

Enterprise Applications:

PHP in a Multitier Environment

The Magazine For PHP Professionals

php|architect

Trang 2

Visit www.zend.com

for evaluation version and ROI calculator

Zend Performance Suite

Reliable Performance Management for PHP

Serve More.

With Less.

The designers of PHP offer you the full spectrum of PHP solutions

Trang 3

and the GD Library

Trang 4

Marco Tabini

Editors

Arbi Arzoumani Brian K Jones Marco Tabini

Graphics & Layout

php|architect (ISSN 1705-1142) is published twelve times a year by Marco Tabini & Associates, Inc., P.O Box 3342, Markham, ON L3R 6G6, Canada

Although all possible care has been placed in assuring the accuracy of the contents of this mag- azine, including all associated source code, listings and figures, the publisher assumes no responsibil- ities with regards of use of the information con- tained herein or in all associated material.

Contact Information:

General mailbox: info@phparch.com Editorial: editors@phparch.com Subscriptions: subs@phparch.com Sales & advertising: sales@phparch.com Technical support: support@phparch.com

Copyright © 2002-2003 Marco Tabini & Associates, Inc — All Rights Reserved

Lately, I’ve been measuring the

progress of php|a in terms of

“brilliant ideas” After a careful

analysis of our history up to this

point, I have noticed that

instead of following a smooth

linear progression based on

con-stant innovation, our ascension

from the ashes of the publishing

world seems to have resulted

from short-lived but intense

flashes of genius, which are then

followed by long periods of

cere-bral inactivity (A related study

also showed that I have way too

much time on my hands, but I

was far too busy to notice or

even care about that)

For example, Arbi came up

with the idea of calling our

mag-azine “php|architect” after I had

been brooding over names like

“The PHP Gazette” and “The

PHP Informer” for days I can

only be thankful for the

com-pletely random sequence of

synaptic signals that made that

brilliant idea come to life

Given the spontaneity of our

collective genius, it would most

definitely prove futile to even try

to explain how we arrived at our

most brilliant idea: to ask Brian

Jones, who joined our editorial

staff last month, to become our

new Editor-in-Chief I can only

say that it was a moment of

unparalleled brilliance I’m sure

that we burned a good number

of those remaining brain cells

which had not yet been fried by

years of exposure to the

radia-tion that our monitors happily

produce to keep us warm, but it

was worth it

This is, therefore, my last

edi-torial as the Editor of php|a I will

still be the Publisher of this

mag-azine and I will do my best to

contribute my thoughts to our

exit(0) column (whose name

was another flash of inspiration,

if I may say so myself), but I willmove on to some of the new ini-tiatives that we have in store foryou, and Brian will take over theentire editorial process of php|a

As my parting words from myeditorial post, let me tell youabout the Editor-in-Chief

The post of Editor-in-Chief isinstrumental in defining thecourse and stature of a maga-zine, and I can only be happythat Brian has decided to acceptour request to take this positionwith us (not to mention howhappy I am that someone elsewill be doing it! But alas, poorfoolish soul that he is, Brian willonly read this once the maga-zine has already hit the virtualstands, and by then his fate will

be sealed)

Naturally, the person who cansport the title of Editor-in-Chiefenjoys a great deal of power—apower that Brian promptlyabused by asking me to rewritethis editorial, claiming that “mythoughts were too fragmented”

As if That could ever Happen

Let me now tell you about thePublisher The post of Publisheraffords great powers as well

That includes the power to editand reject (did I say reject? Imeant “evaluate”) the Editor-in-Chief’s monthly editorial

Regardless of whether histhoughts are fragmented or not

Ah, the bittersweet taste ofrevenge

Trang 5

ionCube Launches New Encoder

British PHP software company ionCube Ltd

released version 2.0 of their standalone Encoder

product last month The new encoder providers

additional features compared to its predecessors,

such as the possibility of creating text headers that

are appended to the encoded files This could be

useful, for example, for creating copyright and

ownership notices, as well as instructions and

how-to guides at the beginning of each file The

Encoder sells for $349.00 US

For more information, you can visit the ionCube

website at :

http://www.ioncube.com/encoder

TechMeridian Releases XAVIOUR

CMS

TechMeridian, a new PHP development

compa-ny based in the United States, has released a

prod-uct called XAVIOUR Web Application Platform

According to TechMeridian, XAVIOUR represents a

combination of the features normally found in

content management and templating systems It

promotes reusability of the code and provides a

flexible framework that can easily be extended by

writing code directly into the templates, if

neces-sary

XAVIOUR is entirely based on PHP and

PostgreSQL, thus providing a platform that can

easily be taken to an enterprise-level of stability

and performance The software product costs

$199.00 US for a single-domain license More

information can be found on the TechMeridian

website at :

http://www.techmeridian.com/xaviour

OpenOSX Updates OpenWeb With

PHP 4.3.0

MacIntosh open-source software provider

OpenOSX have updated their OpenWeb CD

prod-uct to include the latest version of PHP

OpenWeb is a CD compilation of open-source

software for the MacIntosh market designed to

provide publishing and development tools to Web

developers and webmasters Besides technologies

like Apache, PHP and MySQL, it also includes a

shopping card, a content management system

and a graphical management interface

The new 2.5.1 update is available to registered

users of the OpenWeb product free of charge Anew full subscription can be purchased for $60 USfrom the OpenOSX website at :

http://openosx.com/openweb/

2003 PHP Conference in Montréal

This just hot off the press—The Québec PHPAssociation announced that they will be holding aPHP conference in Montréal, Canada, on March20th and 21st The conference will attract a who’swho of the PHP community, from PHP creatorRasmus Lerdorf to Zend-engine co-creator (andphp|a author) Zeev Suraski The conference willinclude sessions in both French and English, and it

is sure to attract visitors from the Americas as well

Trang 6

The simplicity and immediateness of a scripting

lan-guage like PHP is a double-edged sword On the

one hand, everyone has direct access to the source

code; no need to compile for separate platforms and

distribute separate versions of your application On the

other everyone has direct access to the source code,

which makes the protection of intellectual property

really difficult

Let’s face facts, it would be difficult for a software

market to exist without some form of code protection

After all, PHP consultants and software developers are

selling their knowledge, which, for better or for worse,

is somewhat embedded into the source code they

pro-duce The demand for code protection has resulted in

several products which have been developed to make it

possible to limit the functionality of a PHP script (or a

series of scripts) so as to facilitate a commercial

licens-ing scheme

The Zend Encoder, produced by Zend Technologies

(yep, the same folks who wrote the Zend Engine on

which PHP is based) is a rather complete system that

makes it possible to transform a PHP source file into an

“intermediate” representation of itself—that is, a

pre-interpreted set of bytecode instructions that the PHP

interpreter would be able to execute but that are quite

meaningless to a human being The resulting file is

fur-ther mangled to make reverse-engineering almost

impossible In addition, it is possible to require that a

Reviewed For You

By Marco Tabini

The Cost:

$960.00 - $2,880.00 (US) (or less through special small business pricing)

Requirements:

-Supported PHP versions: 4.0.5 up through 4.3.0

-Supported operating systems:

-Linux glibc 2.1 / 2.2 (e.g RedHat 6.x/7.x/8.x, Debian 4.2, SuSE 6.4, Mandrake 8.1, and others)

-The Graphical User Interface is supported under Windows and Linux only

Trang 7

Zend Encoder V.3.1.0

script only run if a special “license file” is present and

provided by the end-user, thus making it possible to

limit the execution of a script to a specific timeframe

(limited trial), or to specific IPs, and so on

InstallationZend installation systems are, in my experience,

among the best ones available to the PHP community

As in most cases, the Encoder is a Java-based

applica-tion that will run on pretty much any platform—the

Zend website allows you to download a version for

Windows, Linux or Solaris

On Linux, the platform I tested it on, the application

is set up through a very straightforward process that

even connects to the Zend website and downloads the

appropriate license code automatically A free 14-day

trial of the Encoder is available, its only limitation being

that your encoded files will only work for three days,

regardless of what settings you choose when

convert-ing them

The User InterfaceOnce installed, the Encoder launched flawlessly—noifs, ands or buts about it It features a neat graphicaluser interface (shown in Figure 1) that makes using thesoftware for the encoding of large numbers of files easyand convenient

As you can see, the interface is based on the concept

of a “project”—this way, you can encode entire tories of PHP scripts at the click of a mouse In fact, Itried to encode the entire php|a website, and the entireoperation took only a few seconds The original fileswere not overwritten (if they were, I’d lose our sourcecode!), but copied over to a destination folder of ourchoosing The program even skipped over our CVSfolders automatically!

direc-The Encoder supports several options designed toenrich the value of encoded files For example, it’s pos-sible to prepend a clear-text header to the file thatallows you to insert installation or usage comments, oreven plain PHP code that is executed if the server is notset up properly to accept encoded files In addition,Figure 1

Trang 8

REVIEWS Zend Encoder V.3.1.0

the Encoder also applies several

opti-mizations to the code while

encod-ing it (although I did not find much

in the way of improvement to our

scripts’ performance I guess we

just write good code!), and it is

pos-sible to require that each encoded

script only work with other encoded

scripts This last feature can be very

important if, for example, your

include files contain your custom

license authentication mechanism

and you don’t want them to be

replaced with dummy versions that

circumvent your scheme

Licensing Capabilities

Perhaps one of the most

interest-ing features of the Encoder is its

abil-ity to encode a project and control

the functionality that an end-user

has access to by issuing a special license file This can be

very useful if you plan to offer specialized “trial”

ver-sions of your application that the end-user can play

with, build upon as needed and then upgrade to a

“full” version by just installing a single file Licensing is

only available if support for it is activated when a script

is encoded

The licensing screen (Figure 2) offers a wide variety of

options, including the ability to limit the execution of

the scripts using constraints such as time or IP or even

a hardware ID that is generated by a small Zend

appli-cation distributed together with the Encoder

Distributing the CodeOnce encrypted, a project can be redistributed by

simply transferring the files to another system

Depending on the settings, you may also need to

dis-tribute a license file

In order to execute your script on a target system,

your customers will need to install a copy of the Zend

Optimizer together with their installation of PHP This is

not normally a big problem, as the Optimizer is a freely

available product whose installation only require a

small change in the php.ini file However, if the

appli-cation is being hosted by a third party, it might be

dif-ficult to convince them to install this software

Advanced Capabilities And

Documentation

In addition to the GUI, the Encoder also features the

necessary tools for encoding scripts and generating

license files on-the-fly through a command-line

exe-cutable This can be helpful if your goal is to hand out

licenses in an automated fashion directly from a site

web-There is no online help for the Encoder, but the lation includes a well-thought-out manual in PDF for-mat that provides plenty of information on using theEncoder, both programmatically and from the GUI.Unfortunately, neither the installation program nor theGUI application itself offers any hints that the docu-mentation itself exists, and this may discourage theless-than-zealous user

instal-Bottom Line

The Zend Encoder is not a cheap product, althoughyou can actually get it very inexpensively through theZend Small Business Program that we illustrated in lastmonth’s issue of php|a ($295.00 US will grant you alicense to the Encoder, the Zend Studio IDE and theZend Performance Suite) However, it is also a verywell-thought-out product that offers ease-of-use andconsistency—something you don’t always find in theworld of PHP

If you’re looking for a way to protect your productsand want the maximum flexibility possible, then I rec-ommend you check this product out If your businessqualifies for the Small Business Program (visit

smallbiz.phpfor more information) I think you willfind that the entire package offers tremendous value at

http://www.zend.com/store/products/zend-a very rehttp://www.zend.com/store/products/zend-asonhttp://www.zend.com/store/products/zend-able price

php|a

Figure 2

Trang 10

The great philosopher and novelist George Santayana

once told us: “Those who cannot remember the past

are condemned to repeat it.”

The past has always been a vital part of the present

Like a map, it tells us where we’ve been and gives us

important information with which to make decisions

about the future If you’re asking yourself what all of

this has to do with PHP, let me show you

Information is critical If you are reading this

maga-zine, your business probably revolves around

informa-tion, and you probably recognize the value of that

information to the people who want it The fact is,

regardless of what your business is, every time someone

visits your site you have the opportunity to capture

use-ful information about them That information can be

used to significantly enhance their experience on your

site, and there are many levels of detail to be had

For instance, you could request that users register

and log in to your site, which usually has required the

provision of at least some personal information on

behalf of the end user You could use this to contact

your customers with promotions or newsletters, or

tar-get their demographic (age, gender, location) with

advertising While the gleaning of this personal data

requires action from the user (ie, voluntary

registra-tion), other types of information can be gathered sively and silently

pas-A prime example of the type of data which can becollected behind the scenes is ‘patterns of use’ informa-tion This can provide invaluable insight into how yoursite is being used, allowing you to make decisionsabout the layout of your site This could influence link

By Peter James

With all of the things to consider when designing and laying out your site, you can quickly become lost and

over-whelmed Usability, accessibility and localization usually require attention before a single line of code is written.

While I can’t possibly hope to cover all of these topics meaningfully in a single article, what I can do is give you some code to implement one very important (and often overlooked) tool to increase your site’s usability: Breadcrumbs.

Information is critical If you are reading this magazine, your business probably revolves around information, and you probably recognize the value of that information

to the people who want it.

PHP Version: 4.0 and Above O/S: Any

Additional Software: N/A REQUIREMENTS

Trang 11

FEATURES Time Travel - Breadcrumbs and History with PHP

placement, advertisement placement and numerous

other factors As an aside, one popular tool that can aid

in the discovery and inspection of this data is

phpOpenTracker

Another silently collected class of data, which will be

our primary focus in this article, is the history of the

cur-rent session This is the most easily handled type of

information We can get it as they navigate, use it

while we have them on the site, and then discard it

when their session ends Unlike many other types of

desirable user data, it doesn’t require a database or the

associated design; it is very transient Interestingly

enough, if stored across sessions, the history provides

patterns of use data, which we mention briefly above

Among many other things, this information can be

used to provide enhanced navigation options, called

‘breadcrumbs’, which is the subject of this article

First, I’ll first explain what breadcrumbs are, and then

I’ll examine in detail the ways in which breadcrumbs

can be used, giving you plenty of usable code along the

way

A note about the coding

style used in my examples

In all of my examples involving sessions, I will use the

$_SESSION[] array, rather than the associated

glob-als Aside from being what I consider to be a cleaner

approach, this will reduce the chance for the

introduc-tion of errors by, for example, missing a

session_register() call I also do not assume in

these examples that you will have

register_glob-als enabled in your php.ini file This will ensure

max-imum compatibility with different systems and PHP

implementations

Of Bread and Crumbs

‘ and Hansel comforted his little sister and said: “Just

wait, Gretel, until the moon rises, and then we shall see

the crumbs of bread which I have strewn about, they

will show us our way home again.’

- Hansel and Gretel - Brothers Grimm, et al

Earning their name from the above-quoted famous

tale, breadcrumbs are a navigation tool that helps the

user find their context, and quickly navigate back to

anywhere in that context Breadcrumbs can be used to

expose the structure of the site to the user, allowing

them to learn the location of items

Usually found near the top of a web page under the

title banner, breadcrumbs can be created using any

server-side or client-side language An example

bread-crumb is shown in Figure A, and a nice, live example of

breadcrumbs can be found at Google’s web directory

at http://directory.google.com/

Figure A

Usability expert Keith Instone tells us that there are

generally two different types of breadcrumbs: location

and path

Location breadcrumbs are useful on hierarchical sites,

and represent a straight line from home (or the root) toyour current location This is similar to a file path in theWindows Explorer location bar, or the output of the

pwd command in Unix, and is what we saw in

Figure A

Path breadcrumbs are much less structured, and

show the actual path you took to your current location,

as in Figure B Hence, if you jump in from a searchengine, you’ll see a breadcrumb with only one crumb.Clicking a link on that page will take you to anotherpage on that site, where you will then see two crumbs,and so forth This can be used on non-hierarchical sites

to supplement with a visual what’s under the browser’sback button

As an aside, it may be that if you used a search engineand looked for “daisy”, you might come across thepage in Figure A directly Strangely, you may still seethe full location breadcrumb, even though you didn’tnavigate through those points This is because pages

on sites that implement location breadcrumbs typicallyknow their way home This can work in a couple of dif-ferent ways, which I’ll discuss a little later

Because they are the most common form, this articlewill focus on the location breadcrumb concept,although I will relate back to path breadcrumbs whenappropriate In fact, the second example that we willcover will actually be a hybrid that looks like a locationbreadcrumb, but the processing underneath is closelyrelated to that of the path breadcrumb method Fromthis point on, unless otherwise noted, when I talk aboutbreadcrumbs I’ll be referring to location breadcrumbs.More About BreadcrumbsBreadcrumbs usually will appear like a directory struc-

Store > Tables > Wines > Tables >

Liquers > Edit

Trang 12

FEATURES Time Travel - Breadcrumbs and History with PHP

ture, which is appropriate since they work best when

you have a highly hierarchical site layout A user can

quickly navigate to any previous level by clicking one of

the links in the breadcrumb For instance, if a user

clicked on the Plants link in Figure A, she would likely

see a page listing the different types of plants, such as

flowers, trees, and grasses The breadcrumb found on

that page might look like Figure C

Figure C

Breadcrumb separators can be anything, including

images, but are commonly one of a number of

semi-intuitive characters, as shown in Figure D

Figure D

The links, such as Home and Monsters above, are links

that contain just enough informtion to get you back to

that place in your session history Depending on your

intention, and the layout of the site, this information

can be very different, ranging from a plain script name

through to a full blown URL (or even a Javascript

func-tion call)

HarveysHTMLHaven.com

Let’s set the stage Harvey is an aspiring business

leader, and his final project while studying for his MBA

required a business idea that related to IT Harvey

thought about it (no pun intended), and decided that

as a part of his business he could resell web code and

graphics All he had to do was browse the web for an

hour or two, and he’d have enough code and images

to start up his business, HarveysHTMLHaven.com

Harvey ended up using a highly hierarchical physical

structure for his site Directories named images and

code resided in his site’s home directory Inside of the

images directory were four more directories named

but-tons, clipart, icons and photos Inside each of these

were, potentially, gif, jpg and png The code directory

had a similarly nested structure For brevity, we’ll focus

only on the images tree.

A user could follow links down any of these paths,

and Harvey was concerned that the user would lose

their bearings and become frustrated He wanted to

maintain some sort of map back to home at all times

Breadcrumbs to the rescue! This is the easiest form of

breadcrumb to implement, because it is a more or less

static structure Sure, Harvey may add images to his

individual library pages, but the category layout ismostly static Let’s write some code

In Figure F, you’ll see a simple class that I created toshow how easy it is to deploy this form of breadcrumb Let’s examine this code I needn’t have used a classhere, but it provides nice encapsulation The class’s job

is to build breadcrumbs from the script’s URL, andreturn the finished product There are two member

variables: $_separator, which contains the

charac-ter used to delimit the links in the breadcrumb, and

$_label_map, which is a list of labels to use for tory names This code works off of the directories inthe script’s URL, and the label map allows us to givethese directory levels descriptive labels, rather than out-put the raw directory names

direc-The class also contains a basic constructor, as well as

a couple of gratuitous setter functions The main

func-tionality, though, comes from get_output(), whichactually produces the breadcrumb Let’s look at how

It first gets the script’s path from the $PHP_SELF

server variable If this class was instantiated from thescript running at

http://www.example.com/foo/bar/index.php

an example of what we’d get from this variable is

/foo/bar/index.php The method then gets thehighest directory in the path, also the current directo-

ry, which in this case would be bar Then it explodes

the path and puts all of the pieces into the $dirs

vari-able

It now loops over all of the entries in $dirs $base

keeps a running concatenation of the directoriesalready processed and is the basis for all links in thebreadcrumb As each directory is processed, the loop

searches for an entry in the $label_map and, if one is found, outputs a breadcrumb using the current $base

value, and the label from the map

Once all of the directories are processed, the

$crumbs are joined together using $separator, and

Home | Plays | Comedies

Home : Cooking : Fish

Home / Monsters / Sully

<?php

// simple example of using SimpleBreadcrumb class

$crumb_label_map = $array ( ‘images’ => ’Images’ , ‘buttons’ => ’Buttons’ , ‘clipart’ => ’Clip Art’ , ‘icons’ => ’Icons’ , ‘photos’ => ’Photographs’ , ‘jpg’ => ’JPEG’ , ‘gif’ => ’GIF’ , ‘png’ => ’PNG’ , ‘code’ => ’Code’ , // etc

Trang 13

FEATURES Time Travel - Breadcrumbs and History with PHP

returned to the caller Figure G contains the code to

use this class for Harvey’s site Harvey simply includes

this file at the point in his page where he wants the

breadcrumb to appear, and he’s in business

The code is very simple A label map is defined, and

the SimpleBreadcrumb class is instantiated using it.

Harvey is happy with the default separator, so he n’t pass any in Finally, he gets the output, and prints

does-it This is a pretty simple class, but it provides verypowerful functionality for a simple directory-orientedsite such as Harvey’s

Although we know that this is a very simple example,

1 <?php

2

3 // a simple breadcrumb class that works off of the directory

4 // names in the current script

34 // get script path, strip any trailing slashes, and

35 // split into constituents

36 // ex /images/icons/gif

37 $dir = $_SERVER [ ‘PHP_SELF’ ];

38 $current = basename ( dirname ( $dir ));

39 $dirs = split ( ‘ / ’ , $dir );

Trang 14

FEATURES Time Travel - Breadcrumbs and History with PHP

let’s mention a couple of its limitations

First, it is dependent on a directory structure, which

makes it very fragile This class simply doesn’t work if

your site is not laid out by directory, since that’s where

the breadcrumbs come from

Second, it doesn’t actually maintain any history

Although the URL in a site structured by directory can

generally be interpreted as the history (if your site is

navigated linearly) the breadcrumbs are still built

directly from it without any regard for querystring

vari-ables, or the path actually taken This severely limits

how flexible this class is

Let’s leave Harvey to his questionable business ideas,

and move on to a more complex situation involving

(almost) everyone’s favorite relative

GrannysGiftGaggle.com

Granny Smith had a dream of being an online

king-pin After some thought, she decided that the best way

to begin her dynasty was to open an e-store, and wait

for the riches to flood in She even started buying

pants with extra-big pockets, so she’d have room for all

the money she was going to make

Her store, GrannysGiftGaggle.com is an emporium of

goodies, from health food to hinges If you can buy it,

you can buy it at Granny’s She has hundreds of

cate-gories and thousands of sub-catecate-gories Let’s examine

the structure a little further

All activity on GrannysGiftGaggle.com comes

through specialized points of access, or controller

scripts, and as I mentioned earlier, there is no really

structured physical underlay for Granny’s site She

mostly relies on the data passed in on the querystring

to get the current state, which determines what to

show

Since the querystring will determine the current

page, it might be educational for us to follow a simple

set of transactions on Granny’s site, and see how

peo-ple navigate around in Figure H

Now that we’ve got the view from 50,000 feet on

how Granny’s site works, we can move on to what we

need to make breadcrumbs work

You may have seen some information in the links

above that might be useful for generating

crumbs This information will provide what

bread-crumbs require: state

State and History

State can be defined as a “unique snapshot that is

quantified by values for a set of variables, characterizingthe web site for a period of time, and is different fromother states.” This is rather like your checkbook Rightnow, if it is balanced, you have a certain set of posses-sions, and a certain amount of money left Your check-book, and life, is in a particular state Writing a checkwill transition you to another state (hopefully not abroke one)

In order to get the information we need for the state,

we must first ask the question: What identifies it? Theanswer to that question depends on the way you’ve putyour site together, and may end up being a very com-plicated question to answer Harvey used his directorynames to identify state, which was very simple Grannydoesn’t really have that luxury, so she will need to per-form a little more magic

While Granny doesn’t have a physically hierarchicalsystem, we can see from the above transaction that shedoes have a home directory, which appears to contain

a products directory and an estore directory This allows

us to use Harvey’s system for part of the breadcrumb

generation The rest of the breadcrumb will need to

be created from the incoming querystrings

Granny’s breadcrumbs will be a little different, notonly in method, but also in construction Granny’sbreadcrumbs will aggregate themselves based on theuser’s history, rather than building fresh on each page,like Harvey’s The reason for this is that Harvey had all

of the states built into each request (because of the

URL), whereas Granny doesn’t The subcategory page

request contains no direct information about whatpage it came from

The user’s history is just a stored collection of past

states As an example, the user’s session history, afterselecting the football category on Granny’s site, wouldcontain the following states

1 Home – no variables, no directories

2 Product Categories – no variables,

products directory

3 Football Sub-Categories – category=football

variable , products directory

This is starting to look suspiciously like a breadcrumb!Let’s see the code to “make it so, Number One” It’slisted in Figure I

It’s ironic that this is the ComplexBreadcrumb class,when the code is almost simpler than the

SimpleBreadcrumb class that we discussed earlier.Regardless, I’ll walk through this code Again, I reallydidn’t need to use a class here, but there it is

The purpose of the class is to store state history in the

Disclaimer: This is obviously not intended to be a

tutorial on how to write a shopping cart

applica-tion, and is only a very rough example, for

demon-stration purposes, of how an application like this

might work.

Trang 15

FEATURES Time Travel - Breadcrumbs and History with PHP

user’s session and allow retrieval of state in breadcrumb

form It has two member variables, $_separator,

and $_current_state $_separator again

con-tains the character used to delimit the breadcrumb’s

links, while $_current_state contains the label of

the current state This label is used as a crude lookup

later

The class also contains a very basic constructor,

which can optionally initialize the breadcrumb

separa-tor at instantiation A setter function is also provided

for this purpose The meat of the class is contained in

the get_output() method This method first checks to

see if a state has been registered for the current page

If not, it returns an empty string

If get_output()did detect a current state, it makes a

non-linked breadcrumb entry for it, and then proceeds

to process the parents of that state For each parent,

the state variables are URL-encoded and links are

pro-duced

Once all of the parents have been processed, the

array of $crumbs is reversed because we built it

right-to-left, but want to display it left-to-right Finally, thecompleted breadcrumb string is returned

Figure J shows a usage example of the

ComplexBreadcrumb class This file could be eitherincluded or embedded in the code that handles thecase where category is set, as in http://grannys-giftgaggle.com/products/?category=foot-ball

This usage code instantiates our new class, and just to

be different, changes the output separator to a forwardslash Since this is specific to the category state, it gets

the category from the $_GET array, and sets the state

accordingly Finally, it gets the output and displays it

I have no doubt that using a little ingenuity specific tothe situation, it would be possible to generalize thisusage code and use it as a common include file, similar

2

http://grannysgiftgaggle.com/prod-ucts/

When the user navigates to the products section,they are presented with a number of product cate-gories

Trang 16

FEATURES Time Travel - Breadcrumbs and History with PHP

21 // - 'parent' is the parent label (allows chaining)

22 // - 'label' is the state/crumb label you are adding

23 // - 'vars' is an array of name-value pairs (usually from $_GET) that

24 // identify the state/crumb

25 function set_state ( $label , $parent = 'home' , $vars =array())

26 {

27 $_SESSION [ '_crumbs' ][ $label ] = array( 'label' => $label ,

28 'path' => $_SERVER [ 'PHP_SELF' ],

37 // no current crumb means no crumb display on the page

38 if (! isset( $this -> current_state ))

39 return '' ;

40

41 $crumbs = array();

42

43 // don't make a link from the current state

44 $crumbs [] = $this -> current_state ;

45

46 // get the current state's parent and set the new current

47 $parent = $_SESSION [ '_crumbs' ][ $this -> current_state ][ 'parent' ];

48 $current = $_SESSION [ '_crumbs' ][ $parent ];

49

50 // do all parents

51 do

52 {

53 foreach ( $current [ 'vars' ] as $name => $value )

54 $values [] = urlencode ( $name ) '=' urlencode ( $value );

55

56 $crumbs [] = "<a href=' { $current [ 'path' ]} ?" join ( '&' , $values ) "'>"

57 " $current [ 'label' ]} </a>" ;

58 // get the current state's parent and set the new current

59 $parent = $_SESSION [ '_crumbs' ][ $this -> current_state ][ 'parent' ];

60 $current = $_SESSION [ '_crumbs' ][ $parent ];

Trang 17

FEATURES Time Travel - Breadcrumbs and History with PHP

You might notice that, with some effort, this more

complex version of breadcrumbing would work for

Harvey as well For his situation, the first method is

more than adequate, and will keep things simple, but

this would certainly do the trick, too

LimitationsAlthough these examples will cover help with the

majority of applications, they still don’t address a few

things:

Using images as separators is not supported This

would be a very simple extension, and would really

only involve the addition of a parameter to the

contruc-tor, an extra setter method, and the extra logic needed

to add an <img> tag, rather than a symbol

Saving $_POST variable state is also not supported.

This is a very simple modification, requiring only that

you change $_GET to $_REQUEST Note that storing

and later resubmitting $_POST values is generally

con-sidered a bad idea, though, since they usually come

from submitted forms, and can have nasty side-effects

(like attempting to re-insert entries to your database

tables) if you aren’t careful

If you are browsing Granny’s site, and you navigate to

two different products in two different categories, you

may find problems with old history If you use your

browser’s back button to back out of the second

prod-uct all of the way back to the first prodprod-uct and refresh,

the categories link in the breadcrumb may be incorrect

This is because each state overwrites any state with the

same name This could be handled by further

identify-ing state usidentify-ing sequences or other methods, but you

will need to determine whether this is really an

impor-tant feature, or just fluff

In the complex example, jumping in from a search

engine, or otherwise browsing in a non-linear fashion is

not supported Because the breadcrumbs are built

incrementally, you would have some difficulty building

a dynamic system like this that responded well to that

situation Two solutions come to mind:

1 default crumbs

2 redirection

‘Default crumbs’ means that if history cannot be

found, default crumbs will be inserted in their place

‘Redirection’ means that if a page is navigated to that

shouldn’t be, the user would be redirected back into

the linear path Both of these are reasonable solutions

in some situations What you do in your situation is up

to you

Applications that use very complex messaging and

event systems may have difficulty fitting into the mold

that breadcrumbs often require Remember, if you face

this task, the fundamental question is ‘what defines

your state at any given moment?’ If you can define

your state minimally, then you are a big step closer tohaving the information you need

We introduced the concept of state history here,which has a number of other uses as well Some ofthese uses include preventing form resubmission, pathbreadcrumbs (remember those?), and in-streamauthentication In-stream authentication refers to a sit-uation in which you click a link, are asked to authenti-cate, and then proceed to that link’s location directly,which is a very nice usability feature

Wrapping UpBoy, we’ve come a long way! I hope these exampleshave helped to clear the mud As with just about any-thing in this world, there are a million ways to imple-ment breadcrumbs I can’t possibly attempt to coverevery base, but I hope that I’ve been able to providesome insight into this topic, and provide some usefulcode to work with

php|a

Peter James is a developer and team lead working in Edmonton, Alberta, Canada In his spare time he tries to magically juggle his family, free- lance work, tool development and learning You can reach Peter at

// get category name

$category = $_GET [ ‘category’ ];

$cbc -> set_state ( “ { $category } categories” , ‘product categories’ , array( ‘category’ => $_GET [ ‘category’ ])

);

print $cbc -> get_output ();

?>

Figure J

Trang 18

Where did it all start?

Few people know this, but when PHP as we know it

today was being molded, back in the summer of 1997,

there were no plans for it to have any object-oriented

capabilities Andi Gutmans and I were working to

cre-ate a powerful, robust and efficient Web language

loosely based on the PHP/FI 2.0 and C syntax As a

matter of fact, we got pretty far without having any

notion of classes or objects – it was to be a purely

struc-tured language One of these summer nights however,

on August 27th that year, this changed

At the time classes were introduced to the code base

of what was to become PHP 3.0, they were added as

syntactic sugar for accessing collections PHP already

had the notion of associative arrays collections, and the

new critters were nothing but a neat new way of

accessing them However, as time has proven, this new

syntax proved to have a much more far-reaching effect

on PHP than originally intended

Another thing that most people don’t know is that by

the time PHP 3.0 came out officially in mid-1998 and

was gaining momentum at a staggering rate, Andi

Gutmans and I were already determined to rewrite the

language implementation Users may have liked PHP

as it existed at the time - in fact we know they liked it.But as the authors of the engine we knew what wasgoing on under the hood and we couldn’t live peace-fully with that The rewrite, which was later dubbed

the ‘Zend Engine’ (Zend being a combination of Zeev and Andi), initiated and became one of the core com-

ponents of the 2nd revolution that PHP experienced injust over a year

This revolution, however, left PHP’s object modelmostly unchanged from version 3 – it was still very sim-ple Objects were still very much syntactic sugar forassociative arrays, and didn’t offer users too many addi-tional features

Objects in the old days

So, what could one do with objects back in the days

of PHP 3.0 or even with the current version of PHP 4.0?Not that much, really Objects were essentially contain-ers of properties, like associative arrays The biggest

difference was that objects had to belong to a class.

Classes, as in other languages, contained a collection ofproperties and methods (functions), and objects could

be instantiated from them using the new operator.

Single inheritance was supported, allowing users to

Trang 19

FEATURES The Object Oriented Evolution of PHP

extend (or specialize) the scope of an existing class

without having to write it from scratch or copy it

Finally, PHP 4.0 also added the ability to call methods

of a specific class, both from within and outside object

contexts

One of the biggest twists in PHP’s history was the fact

that despite the very limited functionality, and despite

a host of problems and limitations, object oriented

pro-gramming in PHP thrived and became the most

popu-lar paradigm for the growing numbers of off-the-shelf

PHP applications This trend, which was mostly

unex-pected, caught PHP in a sub-optimal situation The fact

that objects were not behaving like objects in other OO

languages, and were instead behaving like associating

arrays was beginning to show

The limitations of the old Object ModelThe most problematic aspects of the PHP 3 / PHP 4

object model was the fact that objects were passed

around by value, and not by reference What does that

mean?

Let’s say you have a simple, somewhat useless

func-tion, called myFunction():

As you probably know, the call to myFunction()

will leave $myArgument unchanged; Sent to

myFunction()is a copy of $myargument’s value, and

not $myargument itself This type of argument

pass-ing is called passpass-ing arguments by value Passpass-ing

argu-ments by reference is done by most structured

lan-guages and is extremely useful, as it allows you to write

your functions or call other people’s functions without

worrying about side effects they may have on variables

outside their scope

However, consider the following example:

(The implementation of Woman::setHusband(),

Man::setWife() and areMarried() is left as anexercise for the reader)

What will areMarried() return? We would hopethat the two newlyweds would manage to stay married

at least until the following line of code, but as you mayhave guessed – they wouldn’t areMarried() willconfirm that they got divorced just as soon as they gotmarried Why?

The reason is simple Because objects in PHP 3.0 and4.0 are not ‘special’, and behave like any other kind of

variable, when you pass $joanne and $joe to wed(),you don’t really pass them Instead, you pass clones orreplicas of them So, while their clones end up beingmarried inside wed() , the real $joe and $joanne

remain within a safe distance from the sacrament ofholy matrimony, in their protected outer-scope

Of course, PHP 3 and 4 did give you an option to

force your variables to be passed by reference,

conse-quently allowing functions to change the argumentsthat were passed to them in the outer scope If wedefined wed()’s prototype like this:

then Joanne and Joe would have had better luck (ornot, depending on your point of view)

However, it gets more complicated than that Forinstance, what if you want to return an object from afunction, by reference? What if you want to make

modifications to $this inside the constructor, without

worrying about what may happen when it gets copied

back from new’s result into the container variable?

Don't know what I'm talking about? Say hallelujah

While PHP 3 and 4 did address these problems to acertain extent by providing syntactic hacks to passaround objects by reference, they never addressed thecore of the problem:

The Answer – Zend Engine 2When we were finally convinced that objects areindeed special creatures and deserve their own distinctbehavior, it was only the first step We had to come upwith a way of doing this without interfering with therest of the semantics of PHP, and preferably, withouthaving to rewrite the whole of PHP itself Luckily, thesolution came in the form of a big light bulb thatemerged above Andi Gutmans’ head just over a year

Objects and other types of values are not

created equal, therefore, Objects should be

passed around by reference unless stated otherwise.

function wed (& $bride , & $groom )

function wed ( $bride , $groom )

{

if ( $bride -> setHusband ( $groom )

&& $groom -> setWife ( $bride )) {

wed ( $joanne , $joe );

print areMarried ( $joanne , $joe );

function myFunction ( $arg )

Trang 20

FEATURES The Object Oriented Evolution of PHP

ago His idea was to replace objects with object

han-dles The object handles would essentially be numbers,

indices in a global object table Much like any other

kind of variables, they will be passed and returned by

value Thanks to this new level of indirection we will

now be moving around handles to the objects and not

the objects themselves In effect, this feature means

that PHP will behave as if the objects themselves are

passed by reference

Let’s go back to Joe and Joanne How would wed()

behave differently now? First, $joanne and $joe will

no longer be objects, but rather, object handles, let’s

say 4 and 7 respectively These integer handles point to

slots in some global objects table where the actual

objects sit When we send them to wed(), the local

variables $bride and $groom will receive the values 4

and 7; setHusband() will change the object

refer-enced by 4; setWife()will change the object

refer-enced by 7; and when wed() returns, $joanne and

$joe will already be living the first day of the rest of

their lives together

What does that mean

to end-users?

Alright, so the ending to the story is now more

idyl-lic, but what does it mean to PHP developers? It means

quite a number of things First, it means that your

applications will run faster, as there will be much less

data-copying going around For instance, when you

send $joe to a function, instead of having to create a

replica, and copy over his name, birth date, parents’

name, list of former addresses, social security number

and whatnot – PHP will only have to pass on one object

handle, one integer Of course, a direct result of this is

also a significant amount of memory savings – storing

an integer requires much less space than storing a

full-fledged replica of the object

But perhaps more important, the new object model

makes object oriented programming in PHP much

more powerful and intuitive No longer will you have

to mess up with cryptic & signs in order to get the job

done No longer will you have to worry about whether

changes you make to the object inside the constructor

will survive the dreaded new-operator behavior No

longer will you ever have to stay up until 2:00AM

track-ing elusive bugs! Ok, maybe I’m lytrack-ing with that last

one, but seriously, the new object model reduces the

object-related stay-up-until-2:00AM type of bugs very

significantly In turn, it means that the feasibility of

using PHP for large-scale projects becomes much

easi-er to explain

What else is new?

As one could expect, the Zend Engine 2 packs quite

a few other features to go along with its brand new

object model Some of the features further enhanceobject-oriented capabilities, such as private membervariables and methods, static variables and language-level aggregation Most notable is the revolutionizedinteraction with external component models, such asJava, COM/DCOM and NET through overloading

In comparison to the Zend Engine 1 in PHP 4.0,which first introduced this sort of integration, the newimplementation is much quicker, more complete, morereliable and even easier to maintain and extend Thismeans that PHP 5.0 will play very nicely in your exist-ing Java or NET based setup, as you will be able to useyour existing components inside PHP transparently, as

if they were regular PHP objects Unlike PHP 4.0, thathad a special implementation for such overloadedobjects, PHP 5.0 uses the same interface for all objects,including native PHP objects This feature ensures thatPHP objects and overloaded objects behave in exactlythe same way

Finally, the Zend Engine 2 also brings exception dling to PHP To date, the sad reality is that most devel-opers write code that does not handle error situationsgracefully It’s not uncommon to see sites that spit outcryptic database errors to your browser, instead of dis-playing a well-phrased ‘An error has occurred’ kind ofmessage With PHP, the key reason for this is that han-dling error situations is a daunting task – you actuallyhave to check for the return value of each and everyfunction Since set_error_handler()was added,this issue became slightly easier to manage, as it waspossible to centralize error handling – but it still left alot to be desired Adding exception handling to PHPwill allow developers both fine-grained error recovery,but more important it will facilitate graceful applica-tion-wide error recovery

han-ConclusionThe release of PHP 5.0, powered by the Zend Engine2.0, will mark a significant step forward in PHP’s evolu-tion as one of the key Web platforms in the worldtoday While keeping its firm commitment to userswho prefer using the functional structured syntax ofPHP, the new version will provide a giant leap ahead forthose who are interested in its object oriented capabil-ities – especially for companies developing large scaleapplications

php|a

Zeev has been working for over five years on the PHP project Along with Andi Gutmans, he started the PHP 3 and 4 projects and wrote most of their infrastructure and core components, thereby helping to forge PHP

as we know it today and attracting many more developers to join the movement Zeev is a co-founder and CTO of Zend Technologies Ltd, the leading provider of development and performance management tools for PHP-enabled enterprises Zend’s website is www.zend.com

Trang 22

As a developer, I have always been used to building

most of my own websites from scratch, rather

than using something that other people have

devel-oped When we had to build the php|a site, we

did-n’t even look at any other options—we simply

designed the website the way we wanted it and put it

together The reason is simple: after so many years of

being in this business, I have a pretty good

under-standing of how things work and can take care of

most things more quickly than I can learn how to use

a new product that would do the same in my place

(plus, let’s face it, one always likes to think that his

own stuff is better than something an automated

script can generate)

Unfortunately, this approach does not always work

Building things from scratch—even when it comes to

reusing some of your own code from previous

proj-ects—takes time, and time is money When

budget-ary considerations must take precedence over

person-al pride and the generperson-al laziness that person-all programmers

sport, it’s necessary to look beyond one’s personal war

chest and start from solid building blocks that take

care of most basic (and some advanced) aspects of a

good website

It’s therefore with quite a bit of interest that I look at

the LogiCreate product that we received from Tap

Internet for review this month Now, it’s important tounderstand that the version Tap sent us is a develop-ment snapshot; as such, some of the kinks still need to

be worked out, but this really seems to affect only theinstallation part of the application, and for the rest Ican’t really say that the product exhibits any major

flaws I wish our “development snapshots” were quite

Trang 23

tion framework It provides a set

of modules that can be

integrat-ed into a single website,

provid-ing functionality like content

management, an ad placement

system, an FAQ, a search

func-tion, and more If this sounds

like something that you’ve

already heard, I urge you to read

on—I had exactly the same

impression at the beginning, but

changed my mind as I explored

things in a bit more detail

As with other similar systems,

an entire LogiCreate application

can be managed through an

easy-to-use web-based interface

Unlike other similar systems,

LogiCreate takes a

security-cen-tric approach to the entire

appli-cation Most functions can only

be managed by users who have

the proper permissions, and it’s

possible to push almost all data

that is published through the

website through an approval

process to provide complete

control over it

What’s more, unlike most

con-tent management systems and

web application frameworks,

LogiCreate seems to have been

built with the understanding that

a developer might want to work with something more

than the templates offered by the framework As

such, the creation of custom templates and custom

scripts is not only supported, but also encouraged as a

way to provide a more flexible environment for the

programmer

The Installation Process

As I mentioned above, this is the only area where the

version of LogiCreate that we received still needs a

sig-nificant amount of work The creation of a new

LogiCreate website takes place through a simple

two-step process in which the user is asked to enter only a

few parameters, like the site’s name and database

information (Figure 1) Here, my use of “Marco’s Site”

as the name of the application caused a bit of a

hic-cup—the single quote was not escaped and ended up

in a constant definition, thus confusing the PHP

inter-preter, which threw an error when I subsequently tried

to open my website Note that the installation script

also asks for the database driver that should be used to

access the database Although our version only camewith a driver for MySQL, the entire data access layer isabstracted, and it’s actually possible to extend it tosupport other database systems

The installation process also includes a post-setupphase in which the user is required to adjust the per-missions of the files that have been created Althoughthis requires only four simple shell commands, it couldcertainly have been automated

The simplicity of the installation process, even withits manual portion, is somewhat staggering As youcan see from Figure 2, LogiCreate is a complex piece

of software that includes a large number of modules.For anyone who has ever tried to create a new onlinestore using Microsoft Commerce Server, the two-stepapproach adopted by this application framework isjust plain great

LogiCreate Modules

A total of twelve different modules were packagedwith the version that we received, with functionalityranging from a “welcome page” to a complete con-

Figure 1

Trang 24

tent management system

The modules can be

adminis-tered through the Hercules

Control Center (affectionately

referred to as “Herc”), a backend

web-based application that

allows you to control the

individ-ual settings of each aspect of your

website As I mentioned earlier,

Herc provides a very

well-thought-out user management

system, complete with grouping

and permissions at both the user

and group level Thus, for

exam-ple, if I want to publish a new

news item and type it into the

system (Figure 3), it will be

“parked” into a special repository

until it can be verified and

approved by someone who has

the correct permissions to do so

Herc also provides a complete

statistical system that can be used

to create reports on the kind of

traffic that your site receives

(Figure 4) Although this tool

does not provide the level of

sophistication that a more

spe-cialized web analysis package

offers, it’s still very valuable,

because it produces reports in

realtime, rather than on a specific

schedule

ExpandabilityHow good is an application framework if it can’t be

expanded to meet your actual requirements?

Naturally, it depends: a non-technical person who is

just looking for a quick solution to his problems

prob-ably won’t care that he can’t mess around with the

source code On the other hand, a developer who is

looking for a framework on which to build his website

will.

LogiCreate is clearly slanted towards the latter

approach The system’s templates are really just PHP

scripts that make use of the various classes and

meth-ods made available by each of the application’s

mod-ules This, in my opinion, is the way it should be—

after all, PHP provides an excellent development

envi-ronment, and there simply is no way that any other

artificial “templating system” can match its

functional-ity The core of LogiCreate, therefore, relies heavily on

code reusability and, as such, it is primarily based on

OOP

This, however, does not prevent you from menting your own PHP functionality inside a particu-lar template In fact, that’s the whole point ofLogiCreate’s philosophy: the modules, classes andprocedures that it provides are just there to help you

imple-by providing a simple framework on which you canbuild your own specialized functionality

DocumentationThis is probably another area in which LogiCreateneeds a bit of help The user documentation, com-

Figure 2

A non-technical person who is just looking for a quick solu- tion to his problems probably won’t care that he can't mess around with the source code.

Trang 25

posed primarily of Herc’s user manual, is of excellent

quality and very clear For some reason, however, it is

distributed separately from the Herc interface itself

This makes it difficult for a user to get help from the

system, and risks negating the advantage of having an

interface like Herc in the first place If I were to

devel-op a production system based on LogiCreate,

inte-grating the help in the Herc web pages would

certain-ly be on my to-do list

The developer’s manual is a bit sparse, but otherwise

functional enough to be quite complete It includes

information on how to create new templates and how

to modify (or integrate with) the application

frame-work itself Mercifully, this is not a difficult task to

accomplish by an intermediate-level developer My

only real gripe about the docs is that they contain very

few examples; my experience is that two lines of code

can easily explain what ten lines of text can’t, so I

real-ly hope that the Tap team will add more examples and

sample code to their documentation

The Big PictureFrom a purely technical perspective, I am pleasantlysurprised by how much LogiCreate manages toaccomplish without being over-complicated or requir-ing a week of reading in order to get the proverbial

“Hello, World!” message to appear on the screen

From a business point of view, LogiCreate is notcheap, but given its characteristics can providetremendous value if you consider how long develop-ing the functionality that it provides would take Theproduct is priced at a base of $1,495.00 (US) per serv-

er, plus $500.00 (US) for each additional module thatyou decide to use

Surely, other inexpensive systems provide similarframeworks, but it’s really difficult to find somethingthat is quite as simple to understand and master asLogiCreate Overall, if you’re building a new applica-tion and are looking for a framework to take care ofthe gritty work for you, I’d recommend you take alook at this system

Figure 3

php|a

Trang 26

Figure 4

Trang 27

If I had to take a guess, I would say someone on our

development team asks "so Dave, why can't our

[application server that rhymes with "confusion"]

tem-plates just directly query the database?" at least 5 or 10

times a day (maybe that's just a slight exaggeration) I

then feel compelled to explain the concept once again,

spouting trade-rag-babble about how great n-tiered

architectures are, and the benefits in doing things the

n-tiered way

The developer usually just nods his head humoring

me, then walks away reminiscing of the good old days

when they could just throw everything (including the

kitchen sink) into their code and be done with it But

alas, the logical conclusion is reached all the same that

n-tiered architectures lend themselves perfectly to

applications that must scale and be flexible

If you look at your PHP applications you'll notice a

common pattern This pattern includes things like

con-necting to and querying a database, performing logic

on data, and presenting that data back to the user so

that the user can act (or not act) on what was

present-ed For those of you who have built complex PHP

applications I'm sure that you've noticed that your code

becomes, well complex Maintaining it becomes

rather difficult, if not impossible, especially after taking

a break from it for a few days or even hours You'll also

notice that performance starts to degrade and ideals

like scalability and flexibility start to take a back seat tothe infectious mantra of "just get it working", whichinvades many a development project

If the above scenario strikes a little too close to homefor you, have no fear! The good news is that becausePHP is so accommodating in its openness and its abili-

ty to work happily with other technologies, PHP is quitecomfortable fitting in with an n-tiered architecture Ihope this article will equip you with at least enoughbackground knowledge to get you started with thisinvaluable development/design technique

Before I go on any further, perhaps some explanation

of what I mean by 'n-tiered' would be helpful "Tiers"are like layers Pardon the mixture of metaphors, and Iknow just how tired metaphors are when trying todescribe anything in the application developmentworld, but to think of a program as being comprised of

"layers" is a useful device in clarifying what I'm talkingabout Each "layer" or tier represents a common set offunctionality These layers/tiers in your typical PHPapplication are "coupled", meaning that your presenta-

PHP Version: 4.1.0 or Above O/S: Any

Additional Software: Java SDK 1.4.x AND Java J2EE 1.4.x, JBoss 3.0.4, MySQL

REQUIREMENTS

Trang 28

FEATURES PHP in an N-Tiered World

tion layer is tied to your business logic layer which is in

turn tied to your data layer It's not unlike the days

when the client/server model was king Your client is a

"fat client", containing all of the code needed to not

only display a nice UI, but also to access and

manipu-late the data! Everything (including that kitchen sink) is

stuffed into the client, and the server is nothing more

than a data store This client/server model is still alive

and well today in many Web applications Even though

the web clients are a bit thinner (because the browser

takes care of some UI details), you still notice that

everything is still crammed into that client tier

Now, along comes the n-tiered architecture, which

spreads things out and creates more room for

every-thing by encapsulating these tiers into separate and

identifiable entities The "n" in n-tiered is simply the

mathematical notation for "unknown", meaning that

using this type of architecture assumes nothing about

what is required in order to implement the application

you must develop Essentially, you are no longer

con-fined to a stringent implementation model and are free

to scale and grow as the application and requirements

demand With the n-tiered framework, the application

can scale without the pain of having to re-engineer

everything each time growth is necessary

N-tiered applications are typically broken up into

dis-tinct units of work (tiers) and generally fall into these

The Presentation Layer is often referred to as the

"web tier." This tier contains all of the code to display

the user interface In our example, PHP running on

Apache represents our presentation or web tier

The Business Logic Layer is often thought of as the

"middle tier" This tier is where the vast majority of

business logic is implemented I often think of this tier

as being pretty fuzzy in that it may be comprised of

many smaller tiers, as is the case (to a lesser extent) in

this example The primary business logic component,

in our example, is an EJB But there is a clear distinction

between the EJB and the Data Access Object - the class

which is responsible for doing the "heavy lifting"

-which leads us into the next tier

Data access - This tier is often part of the middle tier,

but is clearly separate from the business logic tier in

that its primary responsibility is in establishing

connec-tions to data stores and querying those data stores In

our example, this is done with the Data Access Object,

which is a Java class running in the J2EE space which

sends queries to the MySQL database and returns data

back to the EJB (the main component of our business

logic layer, as noted above)

Finally, there's the Database Layer This tier is theend of the line, or beginning, depending on how youlook at it This tier represents our data storage tier

Each tier has a very specific purpose and depending

on the complexity of your application each of thesegeneral tiers may be broken up into more specific tiers.For example, the Business Logic tier may be comprised

of business rules that utilize messaging for systems gration, or Data Access tiers may be broken up intoseparate sub-tiers to handle legacy data sources andLDAP or other directory services which also supply data

inte-in some form

In this example I am using PHP as the presentationlayer The presentation layer is responsible for facilitat-ing the actions or events that occur in an application.You'll notice in the example that the PHP code does notcontain any database calls, nor does it contain any busi-ness logic The reason is that PHP, in this example, isresponsible for presenting data and enabling interac-tion between the user and the data Nothing more,nothing less

The "middle tier," the tier that contains the businesslogic and data access tiers, will be implemented using

an EJB (Enterprise Java Bean) in JBoss using the "sessionfacade" design pattern Using this particular designpattern in the J2EE space means we can further sepa-rate our middle tier code into clear distinctionsbetween controller (the EJB) and data access (DataAccess Object) J2EE (Java 2 Enterprise Edition) hasbecome (or is becoming) the defacto standard technol-ogy for the middle tier because of Java's wide accept-ance on most platforms and because Java's object ori-ented design makes modeling business processes muchsimpler However, I must digress, as this is not an arti-cle about the fundamentals of EJB, object orienteddesign principles or JBoss The code I have includedshould provide you with a good launching off point forgetting your feet wet in the middle tier

I have chosen to use MySQL to represent the datatier MySQL is a powerful and robust relational data-base which is free to use This ease of accessibility,along with its compact, simple design makes MySQLperfect for our informal example code There are lots

of other reasons to use MySQL in your applications but

I don't want to get political on you, so on with theshow!

Lets get on with the example, which I think clearlydescribes this n-tiered architecture and also clearly illus-trates the advantages of this type of architecture Thesmall application I am using to illustrate this concept is

a very simple user management program that enablesyou to add and edit a user account Keep in mind thatthis is merely an example and is used only to illustratehow PHP lends itself well to n-tiered applications Ieagerly invite you to take this code and run with it, andturn it into something useful

First things first You will need PHP (obviously) and

Trang 29

PHP in an N-Tiered World

you will need to configure PHP with Java support for

this to work Next you'll need a copy of JBoss

(http://www.jboss.org) JBoss is an open source

J2EE application server Configuring JBoss can be a bit

confusing for those new to the whole Java application

server environment, but there are some excellent

resources such as the JBoss discussion forums and the

Getting Started PDF that can get you up and running

rather quickly Next, you'll need MySQL

(http://www.mysql.org) MySQL is rather simple

to setup and configure - just make sure everything is

running on your local host for this first example Once

you get more comfortable and have the machines to

do so, I would recommend spreading things out a bit

so you can really see how n-tiered architectures enable

logical scaling

Once you have JBoss and MySQL set up, configured

and running, you'll need to run the SQL scripts

provid-ed in the source code for this article (shown in listing

1) Basically you just need a database with a single

table You can use phpMyAdmin

scripts I used phpMyAdmin to generate them, so you

should have no trouble getting them to work

Next, you'll need to create a data source for JBoss that

maps to your MySQL database server and database I

provided my XML configuration files, which I use in my

own JBoss distribution to help give you a leg-up in

get-ting this running Just open up the

phpa_mysql-service.xml file and make the modifications to the

user name and password settings You'll also need to

change the login-config.xml file Please read the

READMEfile I included It should make getting

config-ured and running much simpler

Yes, I am the first to admit that doing this type of

development does have a bit of a steep learning curve,

but once you have gotten comfortable with the whole

notion of application servers and the configurations

surrounding them, all of this will make perfect sense

and become second nature

As part of the source code package you'll notice a

Java JAR file This JAR file contains the EJB classes you

need to deploy (place into the 'deploy' directory in the

JBoss server) You'll also want this JAR file in PHP's class

path This JAR file contains all of the required class files

of the EJB and the client application your PHP program

will use in order to "talk" to the EJB (running in JBoss)

Before we get too much into the source code, take a

look at figure 1 This is a simplification of the design of

the User Management application we'll be looking at

There are some important concepts illustrated in this

figure, one being that the presentation layer does not

directly call the middle tier (EJB) but uses a client

object to perform the work required to instantiate the

EJB and to pass user input into the middle tier

In this example, I use the Java Collections API (Vectors

and Hash tables) to pass data back and forth because

we use the WDDX API to serialize and unserialize thoseobjects into arrays in PHP Because we are dealing withdisparate application platforms (PHP and Java) we need

to pass complex objects from one platform to the nextand WDDX satisfies the requirements in this area rathernicely

Let's start looking at our PHP code in the presentationtier

The interesting stuff starts on line 24 (index.php is

included in this month’s package) Because we areusing an EJB to serve as our business logic - or "middle"tier, we need to establish three variables so that our EJBclient class can locate our EJB remote reference Wecommunicate with our EJB through a remote methodinvocation protocol, and through this protocol ourbusiness methods are said to be "exposed" throughwhat is referred to as a "remote interface."

$factory represents the naming factory interface

JBoss uses to instantiate the naming service $url

points to where JBoss is running, and also indicateswhich remote method invocation protocol we'll be

using $jndiName is the name of the reference in

JBoss's naming service which points to the actual bean's

"home" interface It is through the "home" interfacethat we create an instance of our remote object Iwould recommend checking out

more about EJB

Once we have our EJB "environment" established, wewant to create a Java object in our PHP script Theobject we are creating is an EJB client object This client

is a simple Java class that establishes the connectionbetween the PHP application and the EJB

We first create the object:

Now that we have an object reference for our EJBclient, we can issue method calls against our

$java_obj The first method call we need to issue is

an init() call The UserClient class contains an

init() method that performs the initial contextlookup of the EJB home reference and creates theremote object reference

Okay, so we've gotten all of the boring tal and initialization stuff over with and out of the way.Now we can have some fun!

environmen-To keep things in a single PHP script, I stuck all of thefunctions of this user management application into a

single index.php file The main functionality is

repre-sented by the following PHP functions:

$java_obj -> init ( $factory , $url , $jndiName );

$java_obj = new Java

( "org.ew.phpa.User.clients.UserClient" );

Trang 30

FEATURES PHP in an N-Tiered World

saveChanges

printNewUserForm

printEditUserForm

printEntry

Let's start at the very beginning In the

printEntry() function (which is displayed if you've

just accessed index.php for the first time)

We first start with this:

You'll notice we call a method in our $java_obj

(which if you remember is a reference to our EJB client

`user_id` int(11) NOT NULL auto_increment,

`username` varchar(20) NOT NULL default ‘’,

`password` varchar(100) NOT NULL default ‘’,

`email` varchar(50) NOT NULL default ‘’,

`firstname` varchar(50) NOT NULL default ‘’,

`lastname` varchar(50) NOT NULL default ‘’, PRIMARY KEY (`user_id`)

) TYPE=MyISAM;

Listing 1

Trang 31

PHP in an N-Tiered World

class) In our EJB client, we have a method called

getUsers()which takes no parameters and returns a

WDDX string This getUsers() method in our EJB

client maps directly to our remote EJB method called

getUsers()

The WDDX string is then deserialized (using

wddx_deserialize ($wddx)) into a PHP array Now

that we have our data back from our database (via our

middle tier) we are now ready to do something with it!

Here we are looping through the array, printing

indi-vidual <OPTION> tags for a <SELECT> widget Our

array contains two keys; user_id and username,

which represent the primary data elements needed in

order to paint this entry screen

Now that we have our entry screen displaying a list of

users, we also have an add and an edit button If we

click the add button we just get a nice little HTML form

where we can fill in a user name, password, email

address, first name and last name We have a method

called saveChanges() we'll use as our action()

function, which will be responsible for inserting or

updating our database We'll use the hidden form

vari-able user_id as a flag to help us determine what

action we need to take (if user_id is 0, then we are

inserting Otherwise, we are updating)

Taking a look at saveChanges() you'll notice we

need to first prepare our form data by serializing it in a

WDDX packet:

Once our data is serialized into a WDDX packet we

can call our EJB client:

You'll notice our friend $java_obj In our EJB client

class we have a method called saveUser() which

accepts a single string parameter This parameter is our

WDDX string The EJB client converts (deserializes) the

WDDX packet into a Java hash table Our EJB client

then calls our EJB remote method saveUser() and

passes the deserialized Hash table to the EJB

The $status variable is a simple string which is

returned by our EJB, through our EJB client which, forthis example, just says something like "hey, user infor-mation was saved." In a real application it's usually agood idea to pass back a real status object with errorcodes, meaningful messages and things of that nature The last thing we should take a look at is the

printEditUserForm() function You'll notice thisline of code:

With this one line we call the other business method

in our EJB (via our EJB client class) called getUser().This method takes a single parameter - our user ID

getUser()returns a WDDX string which deserializesinto a PHP associative array This array contains all ofour columns in our database with the values based onthe user ID we passed into our method

There, was that so bad? We went through all of theimportant bits of code to illustrate how we separate ourapplication into logical tiers I hope you noticed that inour PHP code we did not rely on database calls or per-form any business logic Our PHP code just carried outthe task of preparing, sending and displaying data.Something I also hope you noticed with this smallexample is how our application code can directly map

to a requirements document In any major applicationdevelopment project, requirements and design docu-ments play a very large role in the actual project Infact I'd go so far as to say that they may be one of themost important components of a project Using an n-tiered architecture, whoever is wearing the projectmanager's hat can make dividing up the tasks amongstthe specialists more clear, and can produce real esti-mates on the effort required to build each component

Of course this small example hardly scrapes the face of what is possible and it only really describes onemethod of implementation for an n-tiered architecture.There are other technologies and protocols availablelike SOAP and XML-RPC that can be used to divide yourapplication into the multiple tiers

sur-So, leave the kitchen sink right where it is - you don'tneed it in your code Keep your presentation code free

of business logic which, in turn, should be kept free ofyour data access code You'll be happier, accomplishmore and be admired by peers!

$userHash = wddx_deserialize (

$java_obj -> getUser ( $uid )

);

$status = $java_obj -> saveUser ( $packet );

$packet = wddx_serialize_vars ( "username" ,

"password" , "firstname" , "lastname" ,

"email" , "user_id" );

for ( $i = 0 ; $i < count ( $user_array ); $i ++)

{

$uid = $user_array [ $i ][ "user_id" ];

$username = $user_array [ $i ][ "username" ];

echo '<option value="' $uid '">'

$username '</option>' ; }

php|a

Dave is a professional geek specializing in java/j2ee, php (naturally), perl development which is just a cover for his real passion for spending large sums of money on home recording and musical equipment and general-

ly making a nuisance of himself it should also be noted that his / karma

is currently "positive" which will surely fall.

Trang 32

In general, you could say that the purpose of a

tem-plate engine is to bring certain dynamic content into a

flexible, predefined design framework The template

engine we will implement later on in this article will

replace substitution symbols in preformatted HTML

documents with content delivered by PHP scripts This

may sound a little bit unspectacular, but the engine is

quite smart and has a few other useful features It

doesn’t matter if your content consists of a single word

or a whole list of datasets with several rows each Even

arbitrary interlocked datasets can be used to feed a

template In addition, SSIs (server side includes) will be

processed automatically, even if the web server the

script is running on is not capable of processing SSIs

Clean Up Your Code!

There are several good reasons for using a template

engine Probably the most apparent is that it results in

clean and tidy code While one of the greatest

advan-tages of PHP is the ability to embed the PHP source

right into your HTML documents, this mixture of

pro-gramming and formatting languages is also one of the

greatest disadvantages Eventually, the code becomes

impossible to debug and maintain, and as the tion grows larger it begins to look more and more like

applica-‘spaghetti-code’ In addition, if you work on a teamwhere logic and design teams work separately, coordi-nation efforts become quite troublesome

If you’ve ever created large-scale applications withyour PHP code interspersed amongst your HTML,you’re probably well aware of the tremendous effortinvolved in trying to decipher what you or (evenworse) someone else has written; ‘if’ loops are frag-mented by hundreds of lines of HTML code that’s beenwedged between the ‘if’ and ‘else’ statements; just asdisconcerting, every line of HTML seems to have somesmall PHP snippet hidden within These are the night-mares of every PHP programmer tasked with the main-tenance of such “spaghetti-code”, even if it was youwho implemented it in the first place! Thus, in order tosave your soul from this living hell, the pragmatic PHPprogrammer really should be armed with some way ofcreating cleaner, more maintainable, non-nightmareinducing code

develop-started in creating an engine of your own to meet the unique needs of any project.

PHP Version: 4.0 and Above O/S: Any

Additional Software: N/A REQUIREMENTS

Trang 33

Creating a Customized Template-Engine

Using templates can help put an end to this madness

by strictly separating PHP (logic) from HTML (design)

Your code, now free of the extra HTML baggage, will

look more tidy and will be much easier to understand

But wait! There’s more! The separation of logic and

design enables you to easily share work within a team

PHP programmers can focus on their code without

worrying about how to make the output look nice,

while the HTML programmers can design complex

lay-outs without having to understand how the content is

created And there was much rejoicing (yay)

Seems Logical, But How

Does It Work?

Substitution symbols are positioned within the HTML

document to be used as placeholders for the dynamic

content, to be delivered later by PHP In this article, I

will use the term ‘tags’ rather than ‘substitution

sym-bols’, simply because the term tag sounds more

famil-iar to programmers (it’s also shorter) Whatever youdecide to call them, just remember that they will bereplaced with dynamic content by the templateengine

Once you’ve decided to take the plunge into using atemplate-driven development model, several agree-ments between the template designers and the PHPcoders have to be made The most important areas tofocus on are:

- which template tags are needed to integrate the necessary content?

- which HTML elements (e.g dropdown fields or radio buttons), if any, are dependent on PHP code?

- how will form elements later referenced by PHP form processing scripts be named?

Figure 1

Ngày đăng: 17/01/2014, 18:20

TỪ KHÓA LIÊN QUAN