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

Tài liệu It’s All in a Day’s Work ppt

66 651 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 đề Turning a Class into an Application With PHP-GTK
Tác giả Scott Mattocks
Trường học PHP Architect
Chuyên ngành Web Development
Thể loại bài báo
Năm xuất bản 2005
Định dạng
Số trang 66
Dung lượng 3,8 MB

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

Nội dung

fully-fea-DB 1.7.1 DB is a database abstraction layer providing: • An OO-style query API • Portability features that make programs written for one DBMS work with other DBMS's • A DSN dat

Trang 1

INTERVIEW PRIMING PHP FOR THE ENTERPRISEIdealabs Preps LAMP Up for the Big Time

TURNING A CLASS INTO

AN APPLICATION WITH PHP-GTK

Automate your tasks with a GUI appSTRENGTHENING THE AUTHENTICATION PROCESSMake that login more secure without HTTPS

An XML APPROACH TO TEMPLATING USING PHPTAL

Making the peace between designers and developers

Get Ready For:

Trang 3

LEARNING PHP WAS NEVER THIS MUCH FUN

Come learn PHP in Paradise with us

(and spend less than many other conferences)

Ilia Alshanetsky - Accelerating PHP Applications , Marcus Boerger - Implementing PHP 5 OOP Extensions , John Coggeshall - Programming Smarty , Wez Furlong - PDO: PHP Data Objects , Daniel Kushner - Introduction to OOP in PHP 5 , Derick Rethans - Playing Safe: PHP and Encryption , George Schlossnagle - Web Services in PHP 5 , Dan Scott - DB2 Universal Database , Chris Shiflett - PHP Security: Coding for Safety , Lukas Smith - How About Some PEAR For You? , Jason Sweat - Test-driven Development with PHP , Andrei Zmievski PHP-GTK2

The Magazine For PHP Professionals

At php|tropics, take the exam and

Get Zend Certified

and we'll pay your fees!

For more information and to sign up: http://www.phparch.com/tropics

Early-bird discount in effect for a limited time!

Trang 4

HELP! I’m a PHP beauty stuck in the

body of this Java programmer!

Trang 6

EDDIITTOORRIIAALL

air travel—airports and airplanes seem to be a breeding ground

for odd and bizarre behaviour For some unknown reason, the

normal laws of civilized society don’t seem to apply over

interna-tional waters, or as soon as you’ve passed the first (of many)

secu-rity checkpoints

On a flight, you’re forced to be in closer contact than you would

ever allow under any circumstances with people you have never

met in your life—and, most likely, would never want to have

any-thing to do with if you knew them in the first place Some of your

fellow passengers are just plain inconsiderate—like the guy sitting

next to you who takes off his shoes and the other one who drinks

enough Martinis to kill a small horse

Airport security—not to be outdone by the very same people it

is meant to server—is reaching new heights of stupidity At one

end of the line, an officer asks you to take off your shoes “It’s

optional, but if you don’t take them off they’ll search you at the

other end of the line.” Well, duh… let’s see, should I take off my

shoes now or everything else in the presence of that seven-feet-tall

guard named “Bob” in thirty seconds? Um, let me think about it

On my way back from a recent trip to California, I sat right

behind the security checkpoint and listened in on a screener who

was performing a search on a fellow passenger-in-waiting who had

actually refused to take off his shoes The best part was the

intro-duction, which went something like “Sir, could you step to the

side please Now, I will have to perform a search of your person

because you ‘fit the profile.’ Of course, we can’t tell you what the

profile is, but this will only take a moment.”

So, on one side of the line someone tells you exactly “what the

profile is,” and, on the other, someone else tells you that the

pro-file is a secret I hate to be stating the obvious, but that strikes me

as slightly odd—then again, there is no limit to government

silli-ness

Meanwhile, back in Canada our government is training more

search dogs and pigs (yes, I said pigs) to sniff out smugglers

“Drugs,” you may be thinking? No Illegally-imported food It’s

not the guy with the three-pound package of cocaine in his

back-pack that we should be worried about—the real criminal is the

eighty-year-old Italian lady with the salami in her purse

Until next month, happy readings!

php|architect

Volume IV - Issue 3 March, 2005

Publisher

Marco Tabini

Editorial Team

Arbi Arzoumani Peter MacIntyre Eddie Peloke

Graphics & Layout

Christian Wenz

php|architect (ISSN 1709-7169) is published twelve times a year by Marco Tabini & Associates, Inc., P.O Box 54526, 1771 Avenue Road, Toronto, ON M5M 4N5, Canada

Although all possible care has been placed in assuring the accuracy of the contents of this magazine, including all associated source code, list- ings and figures, the publisher assumes no responsibilities with regards

of use of the information contained 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 © 2003-2004 Marco Tabini & Associates, Inc — All Rights Reserved

IItt’’ss AAllll iinn aa

Trang 7

We're proud to announce php|tropics 2005, a new conference that will take place between May 11-15 at the Moon Palace Resort in Cancun, Mexico The Moon Palace is an all- inclusive (yes, we said all inclusive!) resort with over 100 acres of ground and 3,000 ft of private beach, as well as excellent state-of-the-art meeting facilities

As always, we've planned an in-depth set of tracks for you, combined with a generous amount of downtime for your enjoyment (and your family's, if you can take them along with you).

We even have a very special early-bird fee in effect for a limited time only.

For more information, go to http://www.phparch.com/tropics

ZEND Core for IBM

Zend Core for IBM is a complete, certified and fully supported distribution of PHP 5 that

tightly integrates with IBM's DB2 and CloudScape products, in addition to bundling all

required third-party libraries for interaction with the outside world.

The product includes such features as security updates, GUI-based management, granular control over configuration parameters and compatibility with Zend's other products, including Zend Platform.

Zend Core will be available as a free download from both IBM's and Zend's websites in the second quarter of 2005 Support programs and Sevice Level Agreements will also be available for commercial clients in a variety of different configurations.

For more information, visit the Zend Core for IBM site ( h http://www-306.ibm.com/software/data/info/zendcore/ ).

phpBlog 2.0.1

Want to get into the world of

blogging? Are you currently

run-ning phpBB? If so, check out the

latest release of phpBlog 2.0.1

The project’s hompage lists some

of its features as:

dio.php ) Zend Technologies Inc introduced Zend Studio 4.0, a new version of their PHP integrated development envi- ronment (IDE) Zend Studio runs on multiple operating systems including Mac OS X.

The new release includes integrated support for all major database servers, according to the developer, including IBM DB2, Cloudscape, MySQL, Oracle,

MS SQL Server, PostgreSQL, Derby and SQLite New syntax highlighting works for XML and CSS previously PHP, HTML, XHTML and JavaScript were supported PHPDocs support has been added and PHPDocumentor now lets users create documentation directly from the PHP project source code Zend Studio 4 comes in a Standard edition for US$99 and a Professional edition for $299 Both prices include tech support and one year of updates and upgrades.

For more information visit: h http://www.zend.com/ /

Trang 8

NEEWW SSTTUUFFFF

Check out some of the hottest new releases from PEAR.

DB_DataObject_FormBuilder 0.11.4

DDBB DDaattaaOObbjjeecctt FFoorrmmBBuuiillddeerr will aid you in rapid application development using the DDBB DDaattaaOObbjjeecctt and HHTTMMLL QQuuiicckkFFoorrmm packages In

order to have a quick but working prototype of your application, simply model the database, run DataObject's createTable script over it and write a script that passes one of the resulting objects to the FFoorrmmBBuuiillddeerr class The FFoorrmmBBuuiillddeerr will automatically generate a sim- ple but working HHTTMMLL QQuuiicckkFFoorrmm object that you can use to test your application It also provides a processing method that will auto- matically detect if an iinnsseerrtt(()) or uuppddaattee(()) command has to be executed after the form has been submitted

If you have set up DataObject's links.ini file correctly, it will also automatically detect if a table field is a foreign key and will populate a selectbox with the linked table's entries There are many optional parameters that you can place in your DataObjects.ini or in the

properties of your derived classes, that you can use to fine-tune the form-generation, gradually turning the prototypes into tured forms, and you can take control at any stage of the process.

fully-fea-DB 1.7.1

DB is a database abstraction layer providing:

• An OO-style query API

• Portability features that make programs written for one DBMS work with other DBMS's

• A DSN (data source name) format for specifying database servers

• Prepare/execute (bind) emulation for databases that don't support it natively

• A result object for each query response

• Portable error codes

• Sequence emulation

• Sequential and non-sequential row fetching as well as bulk fetching

• Formats fetched rows as associative arrays, ordered arrays or objects

• Row limit support

• Transactions support

• Table information interface

• DocBook and phpDocumentor API documentation

This package provides basic support to localize your application, like locale based formatting of dates, numbers and currencies.

Beside that it attempts to provide an OS independent way to sseettllooccaallee(()) and aims to provide language, country and currency names translated into many languages.

Maguma OpenStudio

Maguma GmbH (Bolzano, Italy) will make the source code of Maguma Studio, Maguma's

Windows-exclusive IDE, open!

Beginning in March 2005 the full source code of Studio will be available for download and community

participation Maguma OpenStudio, as Maguma has named the product, is a milestone in the pursuit to

the realization of Maguma's Open Source strategy Maguma OpenStudio is a fast, easy and effective

PHP IDE for beginners and professional developers alike The newest product, the modular

cross-plat-form IDE, Maguma Workbench, is Maguma’s second generation IDE and is also community focused

through its flexibility to allows users to create custom modules for it Maguma’s goal is to allow

pro-grammers to "Have Fun Programming!" In March Maguma OpenStudio will be available for download

on the Community site w www.phpwizard.net and on the Maguma Community site community h http://com m-

-m

munity.maguma.org/ /

For more information visit: h http://maguma.org

Trang 9

Net_Gopher 1.0.0

An ffooppeenn(()) wrapper for retrieving documents via the gopher protocol It includes additional function for parsing gopher directory

entries.

bz2_filter 1.1.0

A bzip2 compress/decompress stream filter implementation It performs inline compression/decompression using the bzip2 algorithm

on any PHP I/O stream The data produced by this filter, while compatible with the payload portion of a bz2 file, does not include

headers or trailers for full bz2 file compatibility To achieve this format, use the ccoommpprreessss bbzziipp22:://// ffooppeenn wrapper built directly into PHP.

intercept 0.2.0

Allows the user to request that a user-space function be called when a PHP function is executed Support for class/object methods will

be added later.

mailparse 2.1.1

Mailparse is an extension for parsing and working with email messages.

It can deal with rfc822 and rfc2045 (MIME) compliant messages.

eZ publish 3.5.1

Ez.no announces the latest release of their content management system.

From the announcement:

”eZ publish is an open source content management system and development framework As a

content management system (CMS) its most notable feature is its revolutionary, fully

customiz-able, and extendable content model This is also what makes it suitable as a platform for

gener-al Web development Its stand-gener-alone libraries can be used for cross-platform, database independent PHP projects eZ publish is gener-also well suited for news publishing, e-commerce (B2B and B2C), portals, and corporate Web sites, intranets, and extranets eZ publish

is dual licenced between GPL and the eZ publish professional licence.”

Get all the details from h http://ez.no/

The Zend PHP Certification Practice Test Book is now available!

We're happy to announce that, after many months of hard work, the Zend PHP Certification Practice Test Book, written by John Coggeshall and Marco Tabini, is now available for sale from our website and most book sellers worldwide!

The book provides 200 questions designed as a learning and practice tool for the Zend PHP Certification exam Each question has been written and edited by four members of the Zend Education Board the very same group who prepared the exam The questions, which cover every topic in the exam, come with a detailed answer that explains not only the correct choice, but also the question's intention, pitfalls and the best strategy for tackling similar topics during the exam.

For more information, visit h http://www.phparch.com/cert/mock_testing.php p

Trang 10

W hen it comes to transferring data using the

Internet, trying to make your files as small aspossible is often a key element It is rather lit-tle known, however, that PHP supports a variety of

archive formats, in various ways: PHP extensions that

are compiled in (or loaded using pphhpp iinnii settings or

ddll(())), PEAR packages and other external scripts This

article surveys the most important and relevant

possi-bilities in this area, always with short examples that are

ready-to-use for your applications

PHP Extensions

From a performance point of view, using a PHP

exten-sion is very often the best way to solve a problem Since

you’re dealing with compiled code, performance is

usually much better than interpreted PHP code

However, not all of these extensions are updated on a

frequent basis and some of them lack important

fea-tures But before judging, let’s first have a closer look

The file format that is probably most widely used over

the Internet is the ZIP format, because it has been

around for a long time and applications to manipulate

it are widely available on all platforms Recent versions

of Windows come with an internal ZIP module, but do

not support other formats out of the box; Linux

distri-butions and Mac OS X offer much more in this respect

Therefore, in order to avoid the hassle of additionalsoftware installation, using the ZIP format is a goodidea There is even a PHP module that supports ZIP—you can find it in the online manual ath

http://php.net/manual/en/ref.zip.php p The module is

a wrapper for the ZZIPlib library, a SourceForge projectavailable at h http://zziplib.sf.net/ / This library sup-ports only extracting data from an archive, not creatingnew ZIP files Therefore, it can only be used with exist-ing ZIP files Doing so, however, is relatively easy: first,you have to ensure that the PHP module is present Ifyou are building PHP by yourself, you have to run ccoonn ffiigguurree with the ——wwiitthh zziipp==//ppaatthh//ttoo//zzzziipplliibb switch;Windows users just need to add the following line totheir pphhpp iinnii file:

Trang 11

FEEAATTUURREE

Crunching Data with PHP

Under some PHP configurations, the ggddss3322 ddllll file

(which resides in the ddllll subdirectory of your PHP 4

installation) has to be copied into a directory that is in

the system path, e.g cc::\\wwiinnddoowwss\\ssyysstteemm3322; under PHP

5, this DLL is located in the main installation directory

Afterwards, pphhppiinnffoo(())shows that the library is there

Then, accessing the data within the ZIP archive consists

of a number of standard steps:

• Open the ZIP archive with zziipp ooppeenn(())

• Use zziipp rreeaadd(())to iterate through the

con-tents of the ZIP file

• Open one single file within the archive with

zziipp eennttrryy ooppeenn(())

• Read its contents with zziipp eennttrryy rreeaadd(())

• To clean up, use zziipp eennttrryy cclloossee(())and

zziipp cclloossee(())

And here is how it’s done: an archive is opened and its

contents are written to the current directory Here is the

relevant excerpt from the code:

Listing 1 contains the complete code, including a

PHP4-compatible version of ffiillee ppuutt ccoonntteennttss(()),

which is a function available in its native form only inPHP 5 The library also contains some additional func-tions for gathering information about the files in thearchive, including their size

In practice, being only able to extract data is a ous limitation; that’s why there are other classes thatoffer additional functionality You will find them in theuser comments on the ZZIPlib manual page and later

3 function file_put_contents ( $filename , $content ) {

4 if (!( $file = fopen ( $filename , ‘w’ ))) {

13 $archive = dirname ( FILE ) ‘/test.zip’ ;

14 if ( $zip = zip_open ( $archive )) {

15 echo ‘Extracting files <br />’ ;

16 while ( $entry = zip_read ( $zip )) {

17 if ( zip_entry_open ( $zip , $entry , ‘rb’ )) {

18 echo ‘ ‘ zip_entry_name ( $entry ) ‘<br />’ ;

Trang 12

offers a compression mode that takes longer, uses more

memory, but ultimately generates even smaller files

Unfortunately, this functionality is not built-in in many

operating systems and, therefore, only very few

soft-ware packages are available exclusively in BZIP2

Of course, PHP supports BZIP2 by

wrapping the bzip2 library available from

h

http://sources.redhat.com/bzip2/ / Unfortunately, this

module is limited to compressing or decompressing

individual files only Therefore, it is viable for multiple

files only if you first merge them into one tarball (more

information for TAR support can be found later in this

article; it does not come automatically with PHP) Also,

installation of the library is required—then, a run of

ccoonnffiigguurree with the ——wwiitthh bbzz22==//ppaatthh//ttoo//bbzziipp22 switch,

followed by a build will introduce BZIP2 functionality in

your scripts Windows users get the binary module

pphhpp bbzz22 ddllll as part of the official distribution, but have

to explicitly load it using either ddll(())or by adding this

line to their pphhpp iinnii file:

extension=php_bz2.dll

Using the library is easy, and only requires a small

num-ber of steps For compressing data, the following

pro-cedure has to be followed:

• Create a BZIP2 archive using bbzzooppeenn(())

• Use bbzzwwrriittee(())to successively write data to

the archive; the crunching is done ically

automag-• Finally, close the file with bbzzcclloossee(()).Here is a short version of this algorithm that reads inone file and writes it into a BZIP2 archive; Listing 2 con-tains the complete code Note that

ffiillee ggeett ccoonntteennttss(()) is binary-safe and, therefore, itcan be used to retrieve the original file’s contents.Otherwise, you can use ffooppeenn(()) in ‘‘wwbb’’ mode, iteratethrough the file and provide the data to bbzzwwrriittee(())

$infile = dirname( FILE ) ‘/php.ini-recommended’;

$outfile = dirname( FILE ) ‘/test.bz2’;

$out = bzopen($outfile, ‘wb’);

bzwrite( $out, file_get_contents($infile) );

bzclose($out);

The way back, decompressing the files, is performed in

a similar way Here, bbzzrreeaadd(()) is used to progressivelyread all the data out of the archive and decompressedinto its original format It can be stored in a buffer (andthen written to the hard disk using

ffiillee ppuutt ccoonntteennttss(())), or directly saved, piece, using ffppuuttss(()), as seen in the following snippet.Listing 3 contains the complete code

2 $infile = dirname ( FILE ) ‘/test.bz2’ ;

3 $outfile = dirname ( FILE ) ‘/php.ini-recommended’ ;

4

5 echo ‘Uncompressing file <br />’ ;

6 $in = bzopen ( $infile , “rb” );

7 $out = fopen ( $outfile , “wb” );

8 while ( $data = bzread ( $in , 1024 )) {

9 fputs ( $out , $data , 1024 );

2 $infile = dirname ( FILE ) ‘/php.ini-recommended’ ;

3 $outfile = dirname ( FILE ) ‘/test.bz2’ ;

4

5 echo ‘Compressing file <br />’ ;

6 $out = bzopen ( $outfile , ‘wb’ );

Trang 13

The module offers a bit more flexibility if you use the

bbzzccoommpprreessss(())function This compresses a string

provid-ed in the first parameter, using the block size specifiprovid-ed

in the second parameter The block size is a value

between one and nine (included) and has a default

value of 4 However, a value of nine gives the best

com-pression, albeit at the cost of increased system

resources during the data-crunching activity

Finally, PHP supports Zlib, GNU’s ZIP library, which is

installation is required: DIY-compilers have to configure

PHP with the ——wwiitthh zzlliibb==//ppaatthh//ttoo//zzlliibb, whereas

Windows users have this functionality already built-in

(starting with PHP 4.3.0), with no installation,

configu-ration or pphhpp iinnii tweaking required This library is most

often used to GZIP data sent to the browser on the fly,

to make the transfer of web pages smaller and,

there-fore, quicker Nowadays, most web browsers support

this functionality and advertise it by sending the

AAcccceepptt EEnnccooddiinngg:: ggzziipp or AAcccceepptt EEnnccooddiinngg:: ddeeffllaattee

HTTP headers (or both) If this is the case, PHP can send

compressed data across the wire if the following

pphhpp iinnii setting is enabled:

zlib.output_compression = On

Note that (theoretically) nothing can go wrong if the

browser does not support GZIP compression because,

in that case, no corresponding AAcccceepptt EEnnccooddiinngg HTTP

header is sent and, therefore, PHP does not GZIP the

data Older versions of Netscape have a bug with

embedded, compressed media, but do not have a

rea-sonable market share any longer

However, the Zlib extension can also be used to

com-press files on the fly—as well as to uncomcom-press them, of

course In contrast to the ZZIPlib library, this extension

also allows to create archives The standard steps apply,

again with a couple of new function names:

• Create an archive using ggzzooppeenn(())

• Write data to the archive using ggzzwwrriittee(())

• Close the file using ggzzcclloossee(()).Here are the relevant lines (complete code in Listing 4):

$out = gzopen($outfile, ‘wb4’);

gzwrite(

$out, file_get_contents($infile) );

Uncompressing files works in a very similar way:

• Open an archive using ggzzooppeenn(())

• Read data from the archive using ggzzrreeaadd(()),until ggzzeeooff(())returns TTrruuee

• Close the file using ggzzcclloossee(()).Again, here’s a simple snippet of code, taken straightout of the larger example that you can find in Listing 5:

$in = gzopen($infile, “rb”);

$out = fopen($outfile, “wb”);

while (!gzeof($in)) { fputs($out, gzread($in, 1024), 1024);

} gzclose($in);

1 <?php

2 $infile = dirname ( FILE ) ‘/php.ini-recommended’ ;

3 $outfile = dirname ( FILE ) ‘/test.gz’ ;

4

5 echo ‘Compressing file <br />’ ;

6 $out = gzopen ( $outfile , ‘wb4’ );

2 $infile = dirname ( FILE ) ‘/test.gz’ ;

3 $outfile = dirname ( FILE ) ‘/php.ini-recommended’ ;

4

5 echo ‘Uncompressing file <br />’ ;

6 $in = gzopen ( $infile , “rb” );

7 $out = fopen ( $outfile , “wb” );

8 while (! gzeof ( $in )) {

9 fputs ( $out , gzread ( $in , 1024 ), 1024 );

have a bug with embedded,

compressed media, but do

not have a reasonable market

Trang 14

March 2005 PHP Architect www.phparch.com

The Zlib extension offers some other functions,

includ-ing ggzzffiillee(())and ggzzppaasssstthhrruu(()), which work similarly to

ffiillee(()) and ffppaasssstthhrruu(()), but also uncompress data

from the (GZIP) file pointer provided Similarly,

ggzzccoommpprreessss(())allows to directly compress a string (that

was retrieved, for instance, by ffiillee ggeett ccoonntteennttss(())),

whereas ggzzddeeffllaattee(()) uncompresses a GZIP string into

its original form

PHP Streams

Starting with PHP 4.3.0, the concept of streams was

introduced They already existed in previous versions,

but only in a very limited form: as HTTP wrappers for

ffooppeenn(())), or for Zlib (zzlliibb::) However, the latter was

removed from PHP 4.3.0 onwards and replaced by

something less ambiguous PHP now supports a lot of

protocols and wrappers for streams, including two that

can be used to compress data:

• ccoommpprreessss bbzziipp22:://// for BZIP2

• ccoommpprreessss zzlliibb:://// for GZIP, the “successor

wrapper” to the old zzlliibb::

The installation for stream wrappers works analogously

to the procedure we illustrated earlier for PHP

exten-sions For ccoommpprreessss bbzziipp22::////, you need the bzip2

extension (to recall: ——wwiitthh bbzziipp22 if you compile PHP

manually, eexxtteennssiioonn==pphhpp bbzziipp22 ddllll under Windows) If

you want to use GZIP, you have to provide the

compi-lation switch ——wwiitthh ggzziipp, whereas Windows users have

this functionality built-in in their binary distributions

From there on, usage is as simple as working with any

stream—it’s like working with a file You do not have to

worry or care about compressing or uncompressing,

but just work with it like you would with any other PHPstream: just read from or write to it, and PHP takes care

of the rest in a completely transparent fashion Here ishow it’s done for GZIP—a file is read in, compressedand then deflated:

//Compressing

$data = file_get_contents($infile);

file_put_contents(“compress.zlib://$outfile”, $data);

//Uncompressing

$data = file_get_contents(“compress.zlib://$infile”); file_put_contents($outfile, $data);

The download code for this issue contains the completelisting, including a tweak to make it backwards-com-

CVS

1 < <?php

2 i if ( (! ! function_exists ‘ ‘file_put_contents’ )) { {

3 f function file_put_contents $ $filename , $content t ) { {

4 i if ( (!( $file = fopen $ $filename , ‘w’ ))) { {

13 3 $ $infile = dirname _ FILE _ ) ‘/php.ini-recommended’ ’ ;

25 5 $ $infile = dirname _ FILE _ ) ‘/test.bz2’ ;

Trang 15

patible to PHP 4 (where ffiillee ppuutt ccoonntteennttss(())does not

exist); Listing 6 shows the complete source code for the

same task being performed using BZIP2 compression

PEAR Packages

PEAR does not have a category specifically

dedicated to archive files, but for file types

find (as of March 2005) two packages that are relevant

to our quest:

• AArrcchhiivvee TTaarr (p pear.php.net/package/Archive_Tar r)

for tarballs

• AArrcchhiivvee ZZiipp (p pear.php.net/package/Archive_Zip p)

for ZIP files

The first of these two packages is automatically

distrib-uted with PEAR, since the installer uses it to deflate and

install PEAR modules Nevertheless, it might be a good

idea to run ppeeaarr lliisstt uuppggrraaddeess to check whether new

versions exist (or, specifically, ppeeaarr uuppggrraaddee AArrcchhiivvee TTaarr

to install them) Currently, there is no web-based

end-user documentation available in the PHP Manual, only

one generated automatically from the PHPDoc

com-ments in the source code There is also a text file in

PEAR’s ddoocc directory that contains rather detailed

infor-mation about the package Thankfully, the package can

be used in a straightforward manner Again, it’s just a

matter of taking the right steps in the right order:

• First, load the PEAR module: rreeqquuiirree oonnccee

• Once you have created the TAR file, you canadd more files to it using the aadddd(())method,again providing an array of files

• Instead of using an array, you can also vide a space separated list of file names—ifyour file names do not contain spaces

pro-Here is a small example that creates a mini PHP bution: We take three files from a PHP binary distribu-tion package and compress them into a single tarball:

distri-<?php require_once ‘Archive/Tar.php’;

$tar = new Archive_Tar(‘test.tar’);

$tar->create(

‘php4embed.lib recommended dist’);

php.ini-?>

It is also possible to create subdirectories In order to do

so, you can use ccrreeaatteeMMooddiiffyy(())instead of ccrreeaattee(()), or

aaddddMMooddiiffyy(()) instead of aadddd(()) As a second parameter,you need to provide the name of the diretory wherethe files shall be placed:

5 echo ‘Compressing files <br />’ ;

6 $tar -> create ( ‘php4embed.lib’ );

Trang 16

parameter are ‘‘bbzz22’’ for BZIP2 and ‘‘ggzz’’ for GZIP Then,

the PEAR module automatically compresses the files

after merging them into a tarball Thus, you get both

effects: compacting several files into one distribution

tarball and then making the latter’s file size

significant-ly smaller

Extracting files from the TAR/TGZ/TAR’ed BZ2 archive

is even easier to implement: you just open the archive

and then extract its contents to the specified path:

Now to the second relevant PEAR package,

AArrcchhiivvee ZZiipp, which, internally, requires PHP’s Zlib

extension Unfortunately, as of the time of this writing,

the PEAR module has not seen any release yet (an

issue which is, interestingly, also filed as a bug)

However, the module maintainer, Vincent Blavet, does

react to bug reports and currently maintains the

package exclusively in PEAR’s CVS system You find the

also offers web-based access to the repository at

h

http://cvs.php.net/pear/Archive_Zip/ / There, you

will find one file, ZZiipp pphhpp, that you can download and

manually place into the AArrcchhiivvee directory of your PEAR

installation Then, rreeqquuiirree oonnccee ‘‘AArrcchhiivvee//ZZiipp pphhpp’’;;

loads the module Once you have done this, you can

create ZIP archives using this procedure:

• Instantiate the class, providing the target file

name as the parameter

• Create the ZIP archive with the ccrreeaattee(())

method, providing a list of files (as an array

or a comma-separated list)

• Optionally, add further files using the aadddd(())

method

As you can see, the syntax is quite similar to the one

used by AArrcchhiivvee TTaarr The main difference is probably in

the way you can extract files into a specific file location:

you set the aadddd ppaatthh option when using ccrreeaattee(()) or

aadddd(()) The following code snippet shows this; Listing 8

contains the complete code for this example:

);

The file created by this script indeed uses the directoryname provided Getting the files back can be accom-plished with very little code as well: you just need toopen the file and call eexxttrraacctt(()) Again, the aadddd ppaatthhparameter can set a path to be used, this time fordeflating the data in the archive into

<?php require_once ‘Archive/Zip.php’;

$zip = new Archive_Zip(‘test.zip’);

$zip->extract(

array(‘add_path’ => ‘targetdir’) );

?>

Both PEAR packages offer some more functionality, butthe elements I have just shown should fulfill mostrequirements Feel free to explore the source code fur-ther for some interesting insights—and maybe ask themaintainer of AArrcchhiivvee ZZiipp to officially release his (reallynice and functional) package!

Notable External Scripts

Although the methods for manipulating archives usingPHP I have shown so far are excellent, there are alwaysalternatives—one of the good things of Open Source For instance, the SourceForge

project called PKZip library for PHP, available at

h http://sf.net/projects/phpziplib/, provides a nicealternative way to create ZIP archives, but one that hasvery limited support for reading in ZIP files You needthe Zlib extension and, starting from version 0.3, PHP

5 The reason: the author declares his methods as lic or private, which is basically a good thing, but unfor-tunately not supported by PHP 4 However, the rest ofthe module is fully PHP-4-compliant, so all you have to

pub-do to maintain backwards-compatibility is to remove alloccurrences of ppuubblliicc and pprriivvaattee in the code You canthen include the zziipplliibb pphhpp file in your code and followthese steps (great, more lists!):

• Instantiate the class: $$zziipp == nneeww ZZiipplliibb;;

• Add some files with the method

zzll aadddd ffiillee(()), providing the file’s contents,its name and the compression method

A few words about compression methods: the librarysupports three possibilities nn stands for none, bb for BZIPcompression and gg for GZIP compression If the param-eter is not provided, the class automatically uses GZIP.After the character for the compression method, the

March 2005 PHP Architect www.phparch.com

5 echo ‘Compressing files <br />’ ;

6 $zip -> create ( ‘php4embed.lib’ );

Trang 17

compression level follows, ranging from zero (no

com-pression) to nine (maximal compression, both in space

saved and time and memory consumed) Here is a

Listing 9 contains a complete, runnable example

Another package that provides archive manipulation facilities is available at h http://www.php- c

classes.org/browse/package/945.html—and a quicksearch Google will turn up more alternatives

3 function file_put_contents ( $filename , $content ) {

4 if (!( $file = fopen ( $filename , ‘w’ ))) {

14 echo ‘Compressing files <br />’ ;

15 $zip = new Ziplib ;

28 $data = $zip -> zl_pack ( ‘Archive created with PHP!’ );

29 file_put_contents ( ‘test.zip’ , $data );

30 echo ‘done.’ ;

31 ?>

Listing 9

To Discuss this article:

http://forums.phparch.com/204

Christian Wenz is author or co-author of over four dozen books, quently writes for renowned IT magazines and speaks at conferences around the globe He is Germany’s very first Zend Certified Professional, principal at the PHP Security Consortium and maintainer or co-maintain-

fre-er of sevfre-eral PEAR projects.

Have you had your PHP today?

The Magazine For PHP Professionals

Trang 19

FEEAATTUURREE

makes a developer’s life much easier But

almost just as often, the class requires a the

developer to write a script that loads a specific set of

data, which, in turn, can’t be used again I first came

across this problem when writing dozens of scripts that

each loaded a different unit test and simply output the

results I wondered how easy it would be to create an

application that loaded the test cases and showed the

results without having to write the same code over

and over again I came across the same problem

when trying to create PEAR package files—the

PPEEAARR PPaacckkaaggeeFFiilleeMMaannaaggeerr class makes creating PEAR

ppaacckkaaggee xxmmll files easy, but writing the scripts that load

the data drives me crazy That’s when I decided that it

would be easier to create a PHP-GTK application to

col-lect the data than it would be to write those scripts It

turns out that it isn’t that hard at all Hopefully, you will

find the process that I went through helpful when you

find yourself in the same situation that I did

Getting Started

The first thing to do when turning a class into an

appli-cation is to take a good look at what you are starting

with

It is important to understand how you would use the

class in a script if you want to create a useful GUI The

public methods of the class give a good indication as towhat your application should be doing ThePPEEAARR PPaacckkaaggeeFFiilleeMMaannaaggeerr class, for example, has an

aaddddMMaaiinnttaaiinneerr(()) method Therefore, our applicationshould have an “add maintainer” feature This maysound pretty obvious, but consciously thinking about itwill give you a good start on setting up your GUI If youhave an incomplete or confusing layout, you might aswell stick to writing scripts

Lupus in fabula—before getting down to work, we

should probably decide on a general layout for ourapplication The PPaacckkaaggeeFFiilleeMMaannaaggeerr class performsseveral tasks that are mostly independent of one anoth-

er This isn’t to say that you can use just one method

Tired of having to write a new script for every PEAR

pack-age he released, Scott Mattocks decided to wrap the

PEAR_PackageFileManager class in a GUI to make

gener-ating package files a snap The following article details the

process that he went through to create his application and

highlights how you can use PHP-GTK to do the same with

RESOURCES

URL h http://qtk.php.net t

i

Trang 20

and you have a valid package file, but adding a

main-tainer doesn’t rely on the user adding a dependency

first Because of the design of PPEEAARR PPaacckkaaggeeFFiilleeMMaannaaggeerr,

I have decided to use a GGttkkNNootteebbooookk as the main display

widget A GGttkkNNootteebbooookk is a widget with pages that are

marked by tabs; the user can click a tab to bring a given

page to the top I am sure you have seen this type of

layout several times on various websites, or applications

like Mozilla A notebook layout makes it easy to hide

and show only the tools that we need at any given

time The GGttkkNNootteebbooookk also helps keep our GUI small by

letting us stack things in 3-D, instead of having a huge

window with all of the tools displayed at once

Setting up the notebook is easy After you have

creat-ed your notebook object, you just insert or append a

new page whenever you need one A page consists of

a container holding all of the widgets for the page and

a GGttkkLLaabbeell for the tab You may be asking, “Why do I

have to put everything into another container? Why

can’t I just put everything into the notebook page?” A

GGttkkNNootteebbooookk page is a descendant of GGttkkBBiinn, and

descendants of GGttkkBBiinn can only have one child widget

This may sound like a strange limitation, but it isn’t,

really If you only have one child, you don’t have to

worry about ordering, positioning or anything else that

comes along with having multiple child widgets It

keeps the notebook pages simple and leaves the more

complex container stuff to specialized widgets

To allow us to have a page with more than one

widg-et in it, we just need to make sure that the page’s child

is some sort of container that can hold more than one

child of its own, like a GGttkkHHBBooxx Then, we can fill the

child container up withever we want, and the notebook

page will still only have one child

If you look at Listing 1, you’ll notice that I have

sever-al helper methods that take are of creating each page’swidgets Each helper method returns an array holdingthe container for the page, and a label for the tab Youshould also notice that I have connected a method tothe sswwiittcchh ppaaggee signal This is raised any time the toppage of the notebook changes It doesn’t matter if thepage changes because the user clicks on a tab or if ourcode tells the notebook to bring a different page to thefront—by connecting the signal to the sshhoowwWWaarrnniinnggss(())

method, our code will check for any warnings everytime a different page is brought to the front of thenotebook If there are any warnings, our applicationwill bring the user to the warnings page There are fourmethods for connecting signals to callbacks While they

do pretty much the same thing, understanding the ferences between them can save you a lot of headachesdown the road In this instance, I have usedccoonnnneecctt oobbjjeecctt(()) The difference between ccoonnnneecctt(())and ccoonnnneecctt oobbjjeecctt(()) is that ccoonnnneecctt(()) passes thewidget that emitted the signal to the callback function.This is useful when you have one callback that is called

dif-by multiple widgets and you need to know whichwidget emitted the signal ccoonnnneecctt oobbjjeecctt(()), on theother hand, does not pass the widget that emitted thesignal Using ccoonnnneecctt oobbjjeecctt(()) will make the callbackmethods a little more straightforward You’ll see anexample of when you might need to use ccoonnnneecctt(()) alittle later, but in this case it would just complicatethings needlessly

Putting the Pieces Together

Ok So we have our application all set up and ready tostart working The feature we should probably add first

March 2005 PHP Architect www.phparch.com

4 // Create the notebook

5 $this -> notebook =& new GtkNotebook ();

6

7 // Add the addMaintainer page

8 $this -> _addNotebookPage ( $this -> _createSetOptionsPage ());

9

10 // Add the addMaintainer page

11 $this -> _addNotebookPage ( $this -> _createAddMaintainerPage ());

12

13 // Add the addDependencies page

14 $this -> _addNotebookPage ( $this -> _createAddDependenciesPage ());

15

16 // Add the warnings page

17 $this -> _addNotebookPage ( $this -> _createWarningsPage ());

18

19 // When the page is switched, get any new warnings

20 $this -> notebook -> connect_object ( ‘switch-page’ , array(& $this , ‘showWarnings’ ));

21

22 // Return the notebook

23 return $this -> notebook ;

24 }

25

26 function _addNotebookPage ( $page )

27 {

28 // Add the container and the tab label

29 $this -> notebook -> append_page ( $page [ ], $page [ ]);

30 }

31 ?>

Listing 1

Trang 21

is the warnings page This page will be a visual

repre-sentation of the ggeettWWaarrnniinnggss(())method, and will need

to display all of the warnings that are generated when

the user tries to add or change any information The

widget that we want to use to show the warnings

needs to be easy to update and scroll in case there is a

lot of information to display Even though the

underly-ing GTK+ implementation of GGttkkTTeexxtt is technically

“broken,” it is still our best choice in this situation The

GGttkkTTeexxtt widget is very similar to an HTML tteexxttaarreeaa: it

allows for text to be easily added and will scroll when

there is too much to display at one time We can also

set the text area so that the user cannot directly edit the

text—this is a good idea to ensure that nobody

acci-dentally deletes a few lines and then gets confused as

to why their package file didn’t get built properly

The sshhoowwWWaarrnniinnggss(())method that is connected to the

notebook’s sswwiittcchh ppaaggee signal simply grabs the array of

errors from the package file manager and adds each

one on its own line in the warnings area To add the

text, we just call the iinnsseerrtt tteexxtt(()) method of the

GGttkkTTeexxtt widget iinnsseerrtt tteexxtt(()) takes two parameters,

the text to add and the position As with most string

functions in PHP, 11 indicates the end of the string

Listing 2 shows the code for this page

It would be pretty annoying if the warnings just piled

up and there was no way to get rid of them That’s why

I have also added a “clear” button A GGttkkBBuuttttoonn is a

container widget that listens for events from the user,

like pressing a key or clicking with the mouse When a

user clicks on a button, the appropriately named

cclliicckkeedd signal is emitted We want the clear button to

get rid of all of the warnings, so we connect thecclliicckkeedd signal of the clear button to the ddeelleettee tteexxtt(())

method of the GGttkkTTeexxtt widget As you can see, youdon’t always have to connect signals to your own func-tions—you can connect them straight to another wid-get’s methods instead

4 // Pack everything in a vBox

5 $vBox =& new GtkVBox ();

6

7 // Set up the warnings area

8 $this -> warningsArea =& new GtkText ();

9 $this -> warningsArea -> set_editable ( false );

10 $this -> warningsArea -> set_word_wrap ( false );

11

12 // Add a button to clear the warnings area

13 $hBox =& new GtkHBox ();

14 $button =& new GtkButton ( ‘Clear’ );

15 $button -> connect_object ( ‘clicked’ , array(& $this -> warningsArea , ‘delete_text’ ), 0 , - 1 );

16 $hBox -> pack_end ( $button , false , false , 5 );

17

18 // Pack everything in

19 $vBox -> pack_start ( $this -> warningsArea , true , true , 10 );

20 $vBox -> pack_start ( $hBox , false , true );

31 foreach ( $this -> _packageFileManager -> getWarnings () as $warning ) {

32 $this -> warningsArea -> insert_text ( $warning [ ‘message’ ] “\n” , $this -> warningsArea -> get_length ());

Trang 22

Hopefully, you picked up on the two extra arguments

at the end of the ccoonnnneecctt oobbjjeecctt(()) call These two are

user data that will be passed to the callback function

They are passed, in order, after any arguments that are

automatically added by the callback Here, we passed

zero as the start character to be deleted and -1 as the

last character to be deleted When the user clicks on the

clear button, everything in the text area will be

discard-ed If you look at Figure 1, you’ll see that the clear

but-ton appears on the right of the page This is because I

used ppaacckk eenndd(()) instead of ppaacckk ssttaarrtt(()) This function

works just the same way as ppaacckk ssttaarrtt(()), with the

exception that it adds widgets to the end of the

con-tainer For GGttkkVVBBooxxes, this means that widgets are

packed from the bottom of the container up For

GGttkkHHBBooxxes, children are packed from right to left There

will be more on packing widgets in just a few

para-graphs

Next, let’s look at adding a maintainer This is where

we get into really wrapping the PPaacckkaaggeeFFiilleeMMaannaaggeerr

class into our GTK application

A maintainer is someone who contributes to a PEAR

package In the ppaacckkaaggee xxmmll file, they are identified by

four pieces of information: their handle, their name,

their email address, and their role in the package As a

result, the aaddddMMaaiinnttaaiinneerr(())method expects these four

pieces of information as arguments The number and

type of parameters a function takes gives us a clue as to

what kinds of widgets we will need The developer’s

handle, name and email address can be just about

any-thing, so GGttkkEEnnttrryy fields will probably be the best fit A

GGttkkEEnnttrryy is very similar to an HTML text input box It

allows the user to enter one line of text The role, on

the other hand, has some predefined legal values;

therefore, a GGttkkCCoommbboo will work best for this type of

data The layout of this page is going to be a little more

complicated than the one for the warnings page A lot

of developers might use Glade to take care of the

inter-face work, but it really isn’t that difficult and I think you

learn more if you do it yourself

Anyway, let’s get down to business We already have

a method to set up the notebook page that we are

going to use, so all we have to do is add our new

main-tainer widgets We will do this by adding a method

called ccrreeaatteeAAddddMMaaiinnttaaiinneerrPPaaggee(()) This method will

create our information-gathering widgets, plus add a

way for us to get the information to the package file

manager

Take a look at Listing 3—the layout of the widgets is

controlled using a combination of GGttkkVVBBooxxes and

GGttkkHHBBooxxes Take note of the three parameters at the end

of ppaacckk ssttaarrtt(()): these are often forgotten, but can save

you lots of headaches down the road The first, ffiillll,

tells the container whether or not the child widget

should be resized to take up all of the available space

when it is added The second, eexxppaanndd, lets the

contain-March 2005 PHP Architect www.phparch.com

5 $mainVBox =& new GtkVBox ();

6 $mainHBox =& new GtkHBox ();

7 $leftVBox =& new GtkVBox ();

8 $rightVBox =& new GtkVBox ();

9 $subHBox =& new GtkHBox ();

14 // We need three entries and three labels

15 $handleEntry =& new GtkEntry ();

16 $handleLabel =& new GtkLabel ( ‘Handle’ );

17 $nameEntry =& new GtkEntry ();

18 $nameLabel =& new GtkLabel ( ‘Name’ );

19 $emailEntry =& new GtkEntry ();

20 $emailLabel =& new GtkLabel ( ‘Email’ );

21

22 // We also need a combo for the developer role

23 $roleLabel =& new GtkLabel ( ‘Role’ );

24 $roleCombo =& new GtkCombo ();

25

26 // Set up the combo

27 $roleList = $roleCombo -> list ;

28 $roleEntry = $roleCombo -> entry ;

29 $roleList -> set_selection_mode ( GTK_SELECTION_SINGLE );

30 $roleEntry -> set_text ( ‘Select One’ );

31 $roleEntry -> set_editable ( false );

32

33 // Add the roles to the select box

34 $roles = array( ‘Contributor’ , ‘Developer’ , ‘Helper’ ,

‘Lead’ );

35 for ( $i = 0 ; $i < count ( $roles ); $i ++) {

36 $item =& new GtkListItem ();

37 $box =& new GtkHBox ();

38 $label =& new GtkLabel ( $roles [ $i ]);

39 $box -> pack_start ( $label , false , false , 10 );

40 $item -> add ( $box );

41 $roleCombo -> set_item_string ( $item , $roles [ $i ]);

42 $item -> set_data ( ‘role’ , $roles [ $i ]);

43 $roleList -> add ( $item );

44 $item -> show_all ();

46

47 // We need a button to do the work

48 $button =& new GtkButton ( ‘Add Maintainer’ );

49 $button -> connect_object ( ‘clicked’ , array(& $this ,

‘_addMaintainer’ ), $handleEntry , $roleCombo , $nameEntry ,

$emailEntry , $statusLabel );

50

51 // Put it all together

52 // The left VBox is for the labels

53 $leftVBox -> pack_start ( $handleLabel , false , true , 3 );

54 $leftVBox -> pack_start ( $nameLabel , false , true , 3 );

55 $leftVBox -> pack_start ( $emailLabel , false , true , 3 );

56 $leftVBox -> pack_start ( $roleLabel , false , true , 3 );

57

58 // The right VBox is for the entries and the combo

59 $rightVBox -> pack_start ( $handleEntry , false , false , 0 );

60 $rightVBox -> pack_start ( $nameEntry , false , false , 0 );

61 $rightVBox -> pack_start ( $emailEntry , false , false , 0 );

62 $rightVBox -> pack_start ( $roleCombo , false , false , 0 );

63

64 // The two VBoxes go in the main HBox

65 $mainHBox -> pack_start ( $leftVBox , false , false , 2 );

66 $mainHBox -> pack_start ( $rightVBox , false , false , 0 );

67

68 // The subHBox holds the button

69 $subHBox -> pack_end ( $button , false , false , 0 );

70

71 // The label and the two HBoxes go in the main VBox

72 $mainVBox -> pack_start ( $statusLabel , false , false , 4 );

73 $mainVBox -> pack_start ( $mainHBox , false , false , 10 );

74 $mainVBox -> pack_start ( $subHBox , false , false , 2 );

75

76 // Return the page information

77 return array(& $mainVBox , new GtkLabel ( ‘Maintainers’ ));

78 }

79 ?>

Listing 3

Trang 23

er know whether or not it may resize the child widget

when the container is resized The last parameter is the

amount of padding added around the child widget

when it is added to the container The same three

parameters also apply if you are using ppaacckk eenndd(()) If

you have every wondered how to stop widgets from

being bigger than you told them to be, now you know

The GGttkkEEnnttrryy widgets used for the developer’s

han-dle, name and email address are pretty basic, so I am

going to focus on the GGttkkCCoommbboo for the role instead A

GGttkkCCoommbboo is, as its name implies, a combination of a

GGttkkEEnnttrryy and a GGttkkLLiisstt When we set up our page, we

can deal with each piece of the GGttkkCCoommbboo separately, but

still treat them as one widget when it comes time to

position them First, let’s look at the GGttkkEEnnttrryy portion

If we didn’t modify it, the entry part would function just

like any other GGttkkEEnnttrryy in our application, but the

whole idea of using the GGttkkCCoommbboo was so that users had

to select the role from a list, as opposed to typing it

themselves To make sure that only the list values are

used, therefore, we need to prevent the user from

edit-ing the text in the entry area This is done the same way

as we did for the warnings area, with sseett eeddiittaabbllee(())

Setting up the list is a little more complicated; a GGttkkLLiisstt

is a container that will only accept GGttkkLLiissttIItteemms as

chil-dren To add the developer roles, we have to add one

GGttkkLLiissttIItteemm for each When the list items are created,

each one gets tagged with its role This is done using

sseett ddaattaa(()), which is a GGttkkOObbjjeecctt method—this means

that all widgets have it It comes in handy if you just

want to mark an object with a certain value It is easier

for us to call ggeett ddaattaa(())to retrieve the role than it is to

loop through the children of the selected list item

Before we exit from this function, we need to create

a button that we can use to add the new maintainer

information to the package file manager We do this by

first creating a GGttkkBBuuttttoonn, which we will label with ‘Add

Maintainer’ Then, we connect the cclliicckkeedd signal to the

aaddddMMaaiinnttaaiinneerr(()) method In the middle of Listing 3,

you should see that I have decided to use

ccoonnnneecctt oobbjjeecctt(()) for this purpose Again, this is

because the function we are connecting to the cclliicckkeedd

signal does not need to know which button was

pressed and, therefore, doesn’t expect the widget as its

first parameter We add all of the information widgets

to the ccoonnnneecctt oobbjjeecctt(()) call because our method foradding a maintainer needs to extract the developer’sinformation If you try to pass $$eemmaaiillEEnnttrryy

>>ggeett tteexxtt(()), you are passing the return value from thatmethod at the time you connect the signal I have seenmany developers do that and then wonder why theirapplication isn’t working the way they want We need

to pass the widgets themselves so that we can get thereturn value from ggeett tteexxtt(())at the time the user clicksthe button The method can then pass the correct val-ues along to PPaacckkaaggeeFFiillee MMaannaaggeerr::::aaddddMMaaiinnttaaiinneerr(()).After we’ve added the maintainer, it is nice to let theuser know what happened and then clear out the olddata so they can add another developer To do this, wepass one more widget to our aaddddMMaaiinnttaaiinneerr(())

method—a GGttkkLLaabbeell When the user hits the “AddMaintainer” button, we just set the label text to anappropriate message

Ok, that was easy Let’s take a look at something a tle tougher The whole idea of creating our desktopapplication is to make things easier to use Considerwhat it might take to implement the “add dependen-cy” feature We need two pieces for this page: one foradding the packages that can be used as dependencies,the other to show the dependencies that we havealready added For adding the dependencies, we could

lit-do the same thing we did for the add maintainer ture, but that would let the user add anything theywant as a dependency and would open up a lot ofroom for errors It would be a big help to the user if weinstead grabbed the available packages and let themchose from what’s available We can get the list ofinstalled packages by using the PPEEAARR RReeggiissttrryy class,which lets us grab information about installed pack-ages, such as their name, current version number,description, and changelog This will be perfect for get-ting our dependency information, while a GGttkkCCTTrreeeewidget is the perfect choice for displaying it in a hierar-chical fashion We need a hierarchy here because wewant to let the user select not only a particular package

6 $form -> addElement ( ‘text’ , ‘email’ , ‘Email’ );

7 $form -> addElement ( ‘text’ , ‘name’ , ‘Name’ );

“ PHP-GTK isn’t quite as

diffi-cult or scary as its reputation

may have led you to believe “

Trang 24

but also the minimum version needed Listing 4 shows

how to build the tree

After a little set up, we instantiate a PPEEAARR RReeggiissttrryy

object and loop through the results of ppaacckkaaggeeIInnffoo(())

For each package found, we build a node with the

package name as the label We also build a child node

for the version and one node for each version in the

changelog The most important part is the call to

nnooddee sseett rrooww ddaattaa(()) By passing an array containing

the package name and version number, we are tagging

each row with the corresponding information Then,

when the row is selected, we can grab that information

and pass it on to the package file manager If you look

at the manual page for the ttrreeee rrooww sseelleecctteedd signal,

you will see that the callback method gets not only the

tree but also the node that was selected By setting up

our call to ccoonnnneecctt(())and our aaddddDDeeppeennddeennccyy(())

meth-ods, we can grab the right package and version and

pass it on to the package file manager and the widget

that displays the current list of dependencies

To show the current dependencies, I have decided to

use a GGttkkCCLLiisstt widget To set up the list, we need to

pass the number of columns and an array with the

col-umn labels A GGkkttCCLLiisstt is a pretty complex widget if

you get into all the bells and whistles, but all we need

to do is add entries, sort them and resize the columns

as appropriate Let’s start with sorting the columns,

because that is the easiest of our operations After

building the widget, we just call the sseett aauuttoo ssoorrtt(())

method—we don’t need to give it any parameters or

call any other methods The GGttkkCCLLiisstt will now

auto-matically sort our packages by package name and

ver-sion number Simple enough, right?

Now how about resizing the columns? This gets a tle tougher You actually have to pass some parameters

lit-To have the columns automatically resize, call

ccoolluummnn sseett aauuttoo rreessiizzee(())passing the column number(zero in our case) and ttrruuee This will make the first col-umn stretch and shrink to fit its widest entry The othercolumns will adjust as needed without affecting the size

For both parts of this page, it is pretty easy to picturethe widgets running out of room quickly Instead ofmaking our GUI huge to accommodate the lists, we canput each widget inside a GGttkkSSccrroolllleeddWWiinnddooww container.When the child inside the scrolled window gets too big,scroll bars will appear You can control when the scrollbars are visible by setting the scroll bar policy I set thetree’s scrolling window to show the vertical scroll baronly when it is needed and to never show the horizon-tal scroll bar When the user expands the tree, the scrollbar will appear

The next piece to our puzzle is the “set options” ture A lot of the work for PPEEAARR PPaacckkaaggeeFFiilleeMMaannaaggeerr isperformed by sseettOOppttiioonnss(()), which takes an associativearray of options where the key of each element pro-vides the option’s name and the corresponding value

fea-March 2005 PHP Architect www.phparch.com

8 // Check for errors

9 if ( PEAR :: isError ( $result )) {

10 $this -> _pushWarning ( $result -> getCode (), array());

11 //return;

13

14 // Add the dependcy to the clist

15 $list -> insert ( , $data );

17 }

18 ?>

Listing 5

what your application should be doing.”

Trang 25

the option’s value To make things easier for the end

user, each option should be its own widget There are

lots of options that can be set, but I am just going to

focus on one of the more interesting ones—the

pack-age directory

The package directory is the directory that contains

all of the package files The best widget for selecting

files or directories is the appropriately named

GGttkkFFiilleeSSeelleeccttiioonn, which is similar to the save or open

file dialogs you are used to seeing in most applications

A file selection is a big widget that appears on its own

We don’t always want it to be shown, so we will use an

entry to show the file path and a button to show the

file selection when it is needed Setting up the entry

and the button should be pretty much a matter of

rou-tine by now, so let’s jump straight to the file selection

widget

When the “Select” button is clicked, it calls the file

selection’s sshhooww(()) method Because GGttkkFFiilleeSSeelleeccttiioonn

extends GGttkkWWiinnddooww, we can control its position when it

pops up Instead of letting it appear wherever the

oper-ating system feels like, let’s make it show up in the

mid-dle of the screen This is done by calling the ttiioonn(()) method and passing GGTTKK WWIINN PPOOSS CCEENNTTEERR to it.The GGttkkFFiilleeSSeelleeccttiioonn widget is much like GGttkkCCoommbboo, inthat it is a collection of other widgets The two piecesthat we are most interested in are the “OK” and

sseett ppoossii “Cancel” buttons These buttons are not connected toany methods by default, so it is up to us to set them upcorrectly If you try to call a method of a widget prop-erty, PHP-GTK will stop you First, you need to assignthe widget property to another variable After that, youcan call ccoonnnneecctt oobbjjeecctt(()) on the buttons The “OK”button gets connected to a custom method that pass-

es the file path to the GGttkkEEnnttrryy on our main applicationand then hides the file selection window, while the

“Cancel” button gets connected straight to the fileselection’s hhiiddee(())method In both cases, we are usingthe hhiiddee(())method so that we don’t have to rebuild theGGttkkFFiilleeSSeelleeccttiioonn every time the user clicks the “Select”button

The final part of our application is a menu bar thatlets the user save their package file and exit the appli-cation The menu bar needs a menu for file operationsand a menu for help and about information The menubar is the only widget that is going to be outside of thenotebook We’ll put it in the usual place, at the top ofthe window, so that everyone knows where to findthese operations The GGttkkMMeennuuBBaarr widget is a containerspecially designed to hold GGttkkMMeennuuIItteemm widgets These,

in turn, are widgets that can be selected by the userand also hold GGttkkMMeennuus A GGttkkMMeennuu can holdGGttkkMMeennuuIItteemmss Confused yet? Hopefully, Listing 6 willmake it a little clearer Menu items, placed inside menusplaced inside menu items let you have menus that go

as deep as you want

In Listing 6, we start of by creating a GGttkkMMeennuuBBaarr andtwo GGttkkMMeennuuIItteemms, one for the file operations and onefor the help operations When you create a menu item,you need to pass it a string that will be the label for themenu item Each GGttkkMMeennuuIItteemm is appended to the menubar and then has a GGttkkMMeennuu added to it by calling

sseett ssuubbmmeennuu(())and passing a GGttkkMMeennuu to it GGttkkMMeennuuIItteemmsemit the aaccttiivvaattee signal when they are selected; when

we add a sub menu, the aaccttiivvaattee signal is

automatical-ly connected to the sshhooww(())method for the sub menu For each operation, we need to create a newGGttkkMMeennuuIItteemm We then connect the aaccttiivvaattee signal tothe appropriate method For the save operation, weneed to call our own method that calls

ddeebbuuggPPaacckkaaggeeFFiillee(()) and then wwrriitteePPaacckkaaggeeFFiillee(()) ifthere are no problems The exit menu item gets con-nected to the ggttkk::::mmaaiinn qquuiitt(())function

While we are setting up the menus, it is a good time

to add accelerator keys Accelerator keys are the cuts that allow a user to save or exit without goingthrough the entire menu In most applications, CTRL-S

short-is the shortcut for the save function We can implement

4 // Create the menu bar

5 $menuBar =& new GtkMenuBar ();

6 $accel =& new GtkAccelGroup ();

7 $this -> window -> add_accel_group ( $accel );

8

9 // Create the main (only) menu item

10 $fileHeader =& new GtkMenuItem ( ‘File’ );

11 $helpHeader =& new GtkMenuItem ( ‘Help’ );

12

13 // Add the menu item to the menu bar

14 $menuBar -> append ( $fileHeader );

15 $menuBar -> append ( $helpHeader );

16

17 // Create the file menu

18 $fileMenu =& new GtkMenu ();

19 $helpMenu =& new GtkMenu ();

20

21 // Add the menu items

22 $about =& new GtkMenuItem ( ‘Open’ );

23 $about -> connect ( ‘activate’ , array(& $this ,

‘_openFile’ ));

24 $fileMenu -> append ( $about );

25

26 $save =& new GtkMenuItem ( ‘’ );

27 $saveLabel = $save -> child ;

28 $saveKey = $saveLabel -> parse_uline ( ‘_Save’ );

29 $save -> add_accelerator ( ‘activate’ , $accel , $saveKey ,

34 $exit =& new GtkMenuItem ( ‘Exit’ );

35 $exit -> connect_object ( ‘activate’ , array( ‘gtk’ ,

‘main_quit’ ));

36 $fileMenu -> append ( $exit );

37

38 $about =& new GtkMenuItem ( ‘About ’ );

39 $about -> connect ( ‘activate’ , array(& $this , ‘about’ ));

40 $helpMenu -> append ( $about );

41

42 // Complete the menu

43 $fileHeader -> set_submenu ( $fileMenu );

44 $helpHeader -> set_submenu ( $helpMenu );

Trang 26

this function by setting up the menu item in a slightly

different way than we have this far First, we pass an

empty string as the label Then, we grab the menu

item’s label child and use it to create a special label

using ppaarrssee uulliinnee(()) This method takes a string with

an underscore as its only parameter The character after

the underscore will become the shortcut key Next, we

call aadddd aacccceelleerraattoorr(()) The first argument is the signal

that should be emitted when the accelerator key is

pressed, while the second is the GGttkkAAcccceellGGrroouupp for the

entire application This is usually added to the main

window using aadddd aacccceell ggrroouupp(()) The third argument

is the special label that we created

Next, we pass a mask that represents any other keys

that need to be pressed at the same time as the

accel-erator’s main key, like CTRL or ALT To require the user

to press the control button, for example, we pass

GGDDKK CCOONNTTRROOLL MMAASSKK To require Control and ALT, we

would pass GGDDKK CCOONNTTRROOLL MMAASSKK || GGDDKK AALLTT MMAASSKK If we

don’t want the user to have to press any other keys, we

can simply pass zero The final parameter determines

whether or not the shortcut key, along with any

modi-fiers, should be shown to the right of the menu item’s

label After using lloocckk aacccceelleerraattoorrss(()) to make sure

that the shortcuts don’t get changed, we finally

con-nect the aaccttiivvaattee signal to our ssaavveeFFiillee(())method

Wrapping it up

There are many features left to be implemented, butyou should, by now, have a good understanding of thewide range of ways that PHP-GTK can be used to make

a class easier to understand and use

It may take a little longer to create a desktop tion than to do the same work as one script but whenyou have to write dozens of scripts, you might want torethink your strategy a little A well-designed GUI appli-cation can make the developer’s life a breeze I thinkthat I’ve shown that PHP-GTK isn’t quite as difficult orscary as its reputation may have led you to believe.Please feel free to take what we started here andexpand on it It is always interesting to see what otherdevelopers do with the freedom that a desktop GUIallows

applica-F

FEEAATTUURREE

Turning a Class Into an Application With PHP-GTK

To Discuss this article:

http://forums.phparch.com/205

Scott Mattocks is a developer for Yamaha Music Interactive When he isn’t working with PHP and PHP-GTK, he enjoys relaxing at home with his wife and dog If you have any questions or comments feel free to email him at s scottmattoks@php.net t.

Award-winning IDE for dynamic languages, providing a powerful workspace for editing, debugging and testing your programs Features advanced support for Perl, PHP, Python, Tcl and XSLT, on Linux, Solaris and Windows

Download your free evalutation at www.ActiveState.com/Komodo30

Trang 27

NEXCESS.NET Internet Solutions

SITEWORX control panel

/mo SMALL BIZ $ 21 95

NODEWORX Reseller Access

All of our servers run our in-house developed PHP/MySQL

server control panel: INTERWORX-CP

INTERWORX-CP features include:

- Rigorous spam / virus filtering

- Detailed website usage stats (including realtime metrics)

- Superb file management; WYSIWYG HTML editor

INTERWORX-CP is also available for your dedicated server Just visit

http://interworx.info for more information and to place your order

WHY NEXCESS.NET? WE ARE PHP/MYSQL DEVELOPERS

LIKE YOU AND UNDERSTAND YOUR SUPPORT NEEDS!

ORDER TODAY AND GET 10% OFF ANY WEB HOSTING PACKAGE

VISIT HTTP://NEXCESS.NET/PHPARCH FOR DETAILS

D e d i c a t e d & M a n a g e d D e d i c a t e d s e r v e r s o l u t i o n s a l s o a v a i l a b l e

/mo N EX R ESELL 2 $ 59 95

7500 MB Storage

100 GB TransferUnlimited MySQL DatabasesHost Unlimited DomainsPHP5 / MySQL 4.1.XNODEWORX Reseller Access

NEW! PHP 5 & MYSQL 4.1.X

PHP4 & MySQL 3.x/4.0.x options also available

We'll install any PHP extension you need! Just ask :)

MONEY BACK GUARANTEE

FREE DOMAIN NAME

4.1.x

3.x/4.0.x

Trang 28

March 2005 PHP Architect www.phparch.com 28

IINNTTEERRVVIIEEWW

way, and the topic of

Enterprise PHP comes back

into our discussions, one company

has taken matters into its own

hands in a bid to produce a set of

open-source tools that large

organ-izations can depend upon

If the largest fear that an

enter-prise-class organization has of

open-source software is the fact

that it’s not dependable and that

no-one steps up to the plate to offer

the appropriate level of support for

it (what could otherwise be called

the “I have no-one to blame”

fac-tor), Seattle, Washington-based

SourceLabs was founded precisely

with the intent of providing

“certi-fied” software stacks that have been

thoroughly tested and can be

sup-ported in a mission-critical

environ-ment

SourceLabs’ approach to the

problem is, at least on the surface,

very simple They start by building

a “stack” of software based either

on a customer’s needs or on

gener-al common-sense decisions Forexample, in our case this may con-stitute Apache, PHP and MySQL, allrunning on a Linux platform ofchoice

The newly-formed stack is thensubject to a series of tests, whichthe company has collectivelydubbed “CERT-7.” These includeseven different levels of inspections,ranging from security, to scalability,reliability and even regression test-ing Once the stack passes themuster in a particular configuration,they recommend its installation,usage and maintenance and pro-vide support contracts for thosecustomers interested in this type ofservice

While the enterprise-level IT ager will undoubtedly find this serv-ice useful for the peace of mind that

man-it affords in the face of increasing ITscrutiny (especially in large public

companies), the overall conceptcould be really useful for everyonewho uses open-source software formission-critical applications

Don’t Take My Word For It…

A great idea is always backed (ordispelled) by a set or solid, harddata In SourceLabs’ case, this was aparticularly challenging aspect oftheir business, as most of the dataavailable out there is hardly… well,hard at all Therefore, they commis-sioned a full study from Evans Data

to determine whether open-source

in general (and PHP in particular)was anywhere near reaching a level

of acceptance that would justify—

or require—the introduction of ing methodologies and supportedstacks

test-A Friendly Chat

Armed with this information, wethought it might have been a goodidea to let the SourceLabs folks

Interview

Priming PHP for the Enterprise

by Marco Tabini

“PHP in the Enterprise” is beginning

to sound like “the paperless office.”

Luckily, there’s a lot less of a

vapour-ware aura around the former than

around the latter, as this interview

with Cornelius Willis, IdeaLabs’

Vice-president of Sales and Marketing,

Trang 29

speak for themselves and explain to

our readers (and to us—we were

quite curious ourselves) who they

are, what they do, and why the PHP

community should take notice We

hooked up with Cornelius Willis,

SourceLabs’ Vice-president of

Marketing, for a quick Q&A session:

php|architect: Can you

intro-duce our readers to SourceLabs?

Cornelius Willis: SourceLabs

pro-vides tested, certified

pre-integrat-ed open source infrastructure

soft-ware (“stacks”) free of charge, and

sells support and maintenance

sub-scriptions for those stacks While

there are many excellent open

source projects, there are no

certi-fied and supported combinations of

open source systems We are in the

process of assembling and testing

our first downloadable stack, based

on AMP (Apache, MySQL, PHP) and

will continue to test and integrate

stacks in the future

php|a: What is your goal?

CW: We want to transform the

enterprise software market

Software should be provided at

much lower cost and without the

vendor lock-in that has

character-ized so many technology business

models to date Open source

soft-ware provides an instrument that

will allow us to accelerate this

restructuring Our goal is to provide

the best of both worlds: softwarewithout lock-in, that is also depend-able, and backed by the same fullservice support and maintenancethat a legacy enterprise softwarevendor provides today

php|a: What is your target ket?

mar-CW: IT users in Global 2000 panies, ASPs, and ISVs

com-php|a: Can you tell us about CERT7?

CW: CERT7 is our overall testmethodology It’s how we deter-mine and improve the overalldependability of an open sourcestack The testing regime embodied

in CERT7 is similar to that used byinfrastructure software providerssuch as Oracle, IBM, SAP andMicrosoft, but is something that isessentially unprecedented in theopen-source world Open-sourcetesting is usually limited to func-tional testing (e.g.: ”does it work asper the design requirements?”)within the context of a single prod-uct module CERT7 testing takes amore holistic view of the depend-ability and performance of an entireintegrated stack, as Figure 1 callingout “system” level testing indicates

You can find out more aboutCERT7 and subscribe to the CERT7forum at:

h http://www.sourcelabs.com/c7.php p

php|a: Tell us about your LAMP stack

CW: We are currently working on

a certified AMP (Apache, MySQLand PHP) stack, which we will test

on the leading Linux tions We are also consideringdoing a version tested on Windows.We’d be interested in hearing fromthe php|architect community abouttheir interest in such an offering.This distribution will have been test-

implementa-ed and certifiimplementa-ed per the CERT7 testregime, and we will share our certi-fication test results to help buyersunderstand the reliability profile ofthe software in unprecedenteddetail We will also provide criticalupdates as needed and regular serv-ice packs

php|a: How does your LAMP stack fit with Zend’s new Platform product? Are you a competitor?

CW: No Zend Platform is focused

on providing the reliability, ity and interoperability business-critical PHP applications need Itdelivers features that enterprisedevelopers and system administra-tors require: run time diagnostics,performance management, PHPconfiguration and control, andinteroperability with Java.SourceLabs’ AMP stack will be freelydownloadable, and its main feature

scalabil-is its certification process andSourceLabs support contract for it.Customers could definitely use

IINNTTEERRVVIIEEWW

Priming PHP for the Enterprise

CERT7 Test Areas Legacy Enterprise

Software Open Source Software

SourceLabs CERT7 Testing

Unit Functional Testing   

System Functional Testing  

System Stress Testing  

System Scalability Profile  

System Failover Profile  

System Security Testing  

System Regression Testing  

Figure 1

Trang 30

Zend Platform with a SourceLabs

AMP stack

php|a: Why did you commission

the Evans Data report?

CW: We wanted to get a clear

understanding of LAMP stack

adop-tion as we entered the market

Frankly, the data we’d been hearing

directly from IT strategists and

buy-ers was at odds with the hype in the

marketplace, so we wanted to

understand how developers were

spending their precious training

and evaluation time Profiling the

habits and adoption patterns of this

population is what Evans Data

spe-cializes in

The data is fascinating: it shows

that developers are heavily

invest-ing in MySQL, PHP, and Perl, which

is a good leading indicator This is

substantiated by the success of lots

of open-source projects with the

developer community, a

phenome-non that many of us are familiar

with

But our primary research (and

direct interviews with target

Fortune 2000 IT organizations)

shows us that lack of integrated

sys-tems, lack of mission critical

sup-port, and lack of dependability

cer-tification and testing is impeding IT

adoption of open source

infrastruc-ture beyond Linux The conclusion

we’ve reached is that developers, as

one would expect, reflect the

lead-ing edge of a larger trend The

opportunity for SourceLabs is giving

the IT buyer confidence in open

source infrastructure: one throat to

choke for support on integrated,

tested and certified open source

systems, without technology

agen-das or lock-in business models

php|a: Can you give us some of

the important highlights from

the report?

CW: The data gives a fascinating

snapshot of some of the places

where open source development is

growing, and where it is lagging

Some of the highlights:

1) The open source

script-ing languages are strong,but still have a ways to

go to overtake theMicrosoft-supportedscripting languages Thistracks (no surprise)directly to the displace-ment of Windows serverinfrastructure by Linux

This is one of the reasons

we think that a WAMPoffering might be inter-esting to the market, as away to provide a migra-tion strategy for mixed-server shops (See Figure

2 for a breakdown)2) MySQL is widely used,

evaluated, and tested,with 48.5% of databasedevelopers (and it isgaining even more) This

is an example of wherethe gap between whatdevelopers downloadand use and what their

IT gatekeepers are aware

of and sanction, isnotable

3) Adoption of PHP, as a nal indicator of opensource scripting adop-tion, lags in the enter-prise space (just over40% evaluating, intend-ing to or using) with the

IINNTTEERRVVIIEEWW

Priming PHP for the Enterprise

will use or are evaluating

not evaluated or will not use

Trang 31

largest evaluated/will not use response, but

is strongest (near 60% evaluating, intending

or using) among small VARs/SIs This

data-point at once shows the opportunity for

companies like Zend and SourceLabs, and

also the ongoing challenge of delivering

demonstrated dependability that IT

organi-zations demand (See Figure 3)

php|a: What picture does the report paint of

LAMP?

CW: I think the report shows that LAMP is just

enter-ing mainstream adoption now When I talk to people

who are deep in the open software movement, and

who have been using LAMP for years, they often

per-ceive this as a nạve, marketing guy sort of comment

But LAMP has a way to go among US IT buyers who

aren’t used to doing their own testing, integration and

support With some of these services coming on line

from companies like SourceLabs, LAMP is really coming

into its own, and emerging as one of the most

impor-tant platforms of this decade

php|a: How do you see the data provided by the

report changing in the near future?

CW: Clearly, Linux, MySQL and PHP adoption are on

a dramatic upswing Apache is reaching saturation, butmore and more companies are trying out open sourceinfrastructure higher in the stack every day

php|a: What about the long term?

CW: We’ll see a much higher penetration of prise IT shops with LAMP (and other OSS infrastruc-ture); over the next year or two, companies and organ-izations like Zend, Apache, MySQL will play a big part

enter-in this Open-source software gives developers andusers of software a fundamentally better way to trans-act, by cutting out the structural and pricing inefficien-cies of the current business model This is similar to theway Napster restructured our thinking about the musicbusiness At SourceLabs, our goal is to deliver servicesthat will give IT customers confidence in open sourceand in so doing dramatically accelerate that restructuring

F

FEEAATTUURREE

Priming PHP for the Enterprise

Available Right At Your Desk

All our classes take place entirely through the Internet and feature a real, live instructor that interacts with each student through voice or real-time messaging.

What You Get

Your Own Web Sandbox Our No-hassle Refund Policy Smaller Classes = Better Learning

Sign-up and Save!

For a limited time, you can get over $300 US in savings

just by signing up for our training program!

New classes start every three weeks!

http://www.phparch.com/cert

To Discuss this article:

http://forums.phparch.com/206

Trang 33

FEEAATTUURREE

user to login to access different parts of the web

site This process is so common that few users are

confused by a login screen The problem is that when

the user sends this data, it is transmitted in plain text

(assuming you’re not over an HTTPS connection) This

means that anyone who has access to the network can

discover the password by examining the packets that

are sent across it In many cases, the problem doesn’t

warrant the extra expense of an HTTPS connection, but

it would be nice if the password could be sent

encrypt-ed rather than in plain text

This is where the PHP programmer needs to turn

away from PHP and look at how JavaScript can be used

to solve the problem A careful blending of the two

technologies can provide an excellent solution that will

deter all but the most determined hacker

Security is a balancing act between what is the value

of the data or access to certain privileges against the

effort required to get at it through unauthorized

means A bulletin board probably comes fairly low on

the security horizon, whereas credit card data is right

up there with heads of state This article is not a

replacement for security tools like HTTPS, but it can

help with the dozens of low-priority login situations

which barely register a blip on the security radar

Login Screen

I’ve lost count of the number of times that I have

writ-ten a login procedure I would joke that I could do it in

my sleep—and that is when it starts to get dangerous,because I’m coding without thinking, or, at least, I’mnot thinking about the reason for writing the code Infact, let me challenge you to pause for a moment andthink about what is the purpose of a login screen

We request a user to login so that we know who theyare and, once their identity has been established, wecan determine what they can do There are two distinct

parts to this process: authentication and authorization.

The authentication process is about ascertaining whothe person is; the web server says something akin to

“Stop! Who goes there?” while the browsers mayrespond “Don’t worry, it’s only me.” Obviously, the

REQUIREMENTS

PHP 5.x + SimpleXML extension

OS Linux/Unix, Windows Other Software Apache Httpd, Microsoft IIS Code Directory auth

Strengthening the Authentication

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