12 256 11111010 As we said, we can use a regular function as a method of our class; but we can also call a method of another class as one of ours, like so: $retVal = call_user_func_array
Trang 1php | Cruise
March 1 st - March 5 th 2004See inside for details
Get Ready For
Plus:
Introduction to Version
Control with
Discover the power of collaboration CVS
Implementing Web Server
Load Management
Preventing resource overloads
Working with PEAR::XML_Serializer
XML has never been so easy
Trang 3Visit us at www.phparch.com/cruise for more details.
Andrei Zmievski -Andrei's Regex Clinic, James Cox - XML for the Masses,
Wez Furlong - Extending PHP, Stuart Herbert - Safe and Advanced Error Handling
in PHP5, Peter James -mod_rewrite: From Zero to Hero, George Schlossnagle
Profiling PHP, Ilia Alshanetsky Programming Web Services, John Coggeshall
-Mastering PDFLib, Jason Sweat - Data Caching Techniques
We’ve got you covered,
from port to sockets.
Port Canaveral • Coco Cay • Nassau
Plus: Stream socket programming, debugging techniques, writing high-performance code,
data mining, PHP 101, safe and advanced error handling in PHP5, programming smarty,
and much, much more!
Trang 467 Bits & Pieces
Real Interesting Stuff.
Speaker on the High Seas
An Interview with Wez Furlong
Trang 5Existing subscribers
can upgrade to
the Print edition
and save!
Login to your account
for more details.
NEW!
*By signing this order form, you agree that we will charge your account in Canadian dollars for the “CAD” amounts indicated above Because of fluctuations in the exchange rates, the actual amount charged in your currency on your credit card statement may vary slightly.
**Offer available only in conjunction with the purchase of a print subscription.
Choose a Subscription type:
(print + PDF edition)
Your charge will appear under the name "Marco Tabini & Associates, Inc." Please allow up to 4 to 6 weeks for your subscription to be established and your first issue
to be mailed to you.
*US Pricing is approximate and for illustration purposes only.
php|architect Subscription Dept.
VISA Mastercard American Express
Credit Card Number:
Trang 6Graphics & Layout
Sales & advertising: sales@phparch.com
Technical support: support@phparch.com
Copyright © 2002-2003 Marco Tabini & Associates, Inc.
— All Rights Reserved
developer I’ve been using PHP for just over
two years continuously (plus massive
amounts of overtime and hobby
develop-ment), and have made some pretty cool
applications (IMO, at least) Even so, I have
yet to actually touch the vast majority of PHP
extensions And those are just the ones
have been developed that may never be
pro-filed there.
This leads me to my point Often, the
arti-cle ideas submitted to us at php|a deal with
aspects of PHP development that we know
lit-tle about As technical editors, though, it is
our job to ensure that the material presented
here is as accurate as possible, which forces us
to (as much as possible) fully understand and
grasp the technology being discussed This
presents incredible opportunities for learning
and growth.
I really think that there are stages in
knowl-edge When you first start out learning
some-thing, you are ignorant and you (usually)
make no bones about it As your knowledge
grows, you can quickly and easily become
cocky and arrogant This cocky and arrogant
attitude usually succeeds giving you plenty of
humble pie to eat, which manages to
eventu-ally settle you into the comfortable stage
where you know what you’re doing, but
aren’t going to make a big deal out of it.
When I look back at the time I’ve been at
php|a, and the articles I’ve worked with, I’m
astonished at how much I’ve learned When I
started at php|a, I was definitely in the “armed
and dangerous” camp I knew it all After a
number of months working with some of
PHP’s best and brightest, I now realize that I
know nothing, and should just shut up.
It’s unfortunate, therefore, that I must leave
php|a I’ve really enjoyed working with
every-body here, as well as you readers You’re the
reason we burn the midnight oil bringing you
the best that the community has to offer
every month Your feedback and comments
every month help us create a better
Trang 7publica-tion one that we can all be proud of Many of our readers are also our authors, and I’ve very much enjoyed working with you as well Your seemingly limitless practical knowledge of PHP has brought much enlightenment to the team here, and we thank you for that, as well as for the excellent articles that you offer us.
Of course, php|a will continue I mean, where would it go? Brian Jones will return as “Guest Editor-in-Chief” for the December issue, which is our first anniversary and will feature some of the best content yet (of course!), and our own Marco Tabini will do the honours again starting with January Good luck Marco!
Until then
php|a
PHP.net announced the release of PHP
4.3.4
The latest version of the 4.0 branch of PHP, 4.3.4, has
been released to the public It contains, among other
things, these fixes, additions and improvements:
• Fixed disk_total_space()and
disk_free_space()under FreeBSD
• Fixed FastCGI support on Win32
• Fixed FastCGI being unable to bind to a specific
IP
• Fixed several bugs in mail() implementation
on win32
• Fixed crashes in a number of functions
• Fixed compile failure on MacOSX 10.3 Panther
• Over 60 bug fixes
For more information, visit www.php.net.
PEAR 1.3b3
PEAR has released of the PEAR Base system
The PEAR package contains:
• the PEAR base class
• the PEAR_Error error handling mechanism
• the PEAR installer, for creating, distributing
and installing packages
• the OS_Guess class for retrieving info about
the OS where PHP is running on
What’s New!
PHP 5.0.0 Beta 2Can’t wait until PHP5? Well,
we are one step closer withthe latest Beta 2 release of thenew version of PHP
PHP.net announced: ”This is the first featurecomplete version of PHP 5, and we recommend forPHP users to try it PHP 5 is still not ready for pro-duction use!
Some of the more major changes include:
• PHP 5 features the Zend Engine 2
• XML support has been completely redone inPHP 5, all extensions are now focusedaround the excellent libxml2 library(http://www.xmlsoft.org/)
• SQLite has been bundled with PHP Formore information on SQLite, please visittheir website
• A new SimpleXML extension for easilyaccessing and manipulating XML as PHPobjects It can also interface with the DOMextension and vice-versa
• Streams have been greatly improved,including the ability to access low-levelsocket operations on streams
There have been many changes since Beta 1,some of them documented in the NEWS file andmost language changes are documented inZEND_CHANGES “
Trang 8• the System class for quick handling common
operations with files and directories
Changes in this release include changes to the PEAR
installer
Get a taste of the new PEAR at PEAR.PHP.net
PhpDocumentor 1.2.3
phpDocumentor is a JavaDoc-like automatic
documen-tation generator for PHP written in PHP
The phpDocumentor team announces:
“The phpDocumentor team is pleased to announce
the release of phpDocumentor 1.2.3
This is a bugfix maintenance release Only a few small
bugs have been found and fixed
Notice: PEAR users will want to read the release notes
for directions on how to automatically setup the web
inter-face on install”
Get all the files and more information from the
pro-ject’s Sourceforge page at:
http://sourceforge.net/projects/phpdocu/
PHP2Go
Sourceforge.netannounces the release of PHP2Go, a
web development framework
The release announces: “After 12 months of
develop-ment, we are very proud to announce that the first beta
version of PHP2Go Web Development Framework was
released We strongly recommend that you don’t use this
first beta version in a production environment Soon, the first stable releases will be available here or at the project area in SourceForge.net.
In this development period, almost 100 classes were ated and tested Almost all common features needed by a small, medium or high web application were included in the framework However, the documentation of this first release is still poor In a huge framework, that may be used
cre-to act like a basement cre-to the development of one or more applications, documentation, tutorials and help stuff are very important Because of that, as the time goes by, the complete instructions on how to build simple or complex stuff for your Web applications using PHP2Go will be avail- able here.
For now, we suggest that you make your first experience with PHP2Go Bug reports, suggestions or any doubts will
What is it?
Objectkitchen is a Java application used through aclient/server-style connection from your application Itwas written with the following goals in mind
It should be very easy to use An average mer should be able to start storing and retrieving objectdata within 15 minutes of installation
program-MySQL.com announces the release of MySQL version 4.0.16.Some changes mentioned in the changelog include:
• Added the following new server variables to allow more precise memory allocation:
rraannggee aalllloocc bblloocckk ssiizzee, qquueerryy aalllloocc bblloocckk ssiizzee, qquueerryy pprreeaalllloocc ssiizzee,
ttrraannssaaccttiioonn aalllloocc bblloocckk ssiizzee, and ttrraannssaaccttiioonn pprreeaalllloocc ssiizzee
• mmyyssqqllbbiinnlloogg now reads options files To make this work one must now specify ——rreeaadd ffrroomm rreemmoottee sseerrvveerrwhen reading binary logs from a MySQL server (Note that using a remote server is deprecated and maydisappear in future mmyyssqqllbbiinnlloogg versions)
• Block SSIIGGPPIIPPEE also for non-threaded programs The blocking is moved from mysql_init()to
mysql_server_init(), which is automatically called on the first call to mysql_init()
• Added ——lliibbss rr and
——iinncclluuddee options to mmyyssqqll ccoonnffiigg
• New ``>> prompt for mysql This prompt is similar to the ‘‘>> and ““>> prompts, but indicates that an
identifi-er quoted with backticks was begun on an earliidentifi-er line and the closing backtick has not yet been seen
Get more information or download from MySQL.com
Trang 9It should be usable from a multitude of languages,
but with primary focus on PHP and Java
It should provide natural mapping of an
object-ori-ented design Relations between objects should just
work without any extra work
It should fast enough to be usable for reasonably
busy websites
The best way to discover what objectkitchen is
actu-ally about is to read the language introduction Its a
small one-page document, which provides you with an
easy to read example using PHP as the client language
Get more information from:
Objectkitchen.narcissisme.dk.
ADOdb 4.00
PHPeverywhere announces the release of ADOdb 4.00
The release announces: ”ADOdb 4.00 is out after a 3
month beta testing process
The distinguishing feature of this release is the
perform-ance monitoring functionality AFAIK, it is the first Open
Source cross-platform, multi-database performance
moni-toring and health check software in the world
It features:
• A quick health check of your database server
using $$ppeerrff >>HHeeaalltthhCChheecckk(())or $$
ppeerrff >>HHeeaalltthhCChheecckkCCLLII(()).
• User interface for performance monitoring,
$$ppeerrff >>UUII(()) This UI displays:
- the health check,
- all SQL logged and their query plans,
- a list of all tables in the current database
- an interface to continiously poll the server
for key performance indicators such as CPU,
Hit Ratio, Disk I/O
• Gives you an API to build database monitoring
tools for a server farm, for example calling
$$ppeerrff >>DDBBPPaarraammeetteerr((‘‘ddaattaa ccaacchhee hhiitt rraattiioo’’))returns this
very important statistic in a database
indepen-dant manner “
Get more information from PHPEverywhere at:
http://php.weblogs.com/2003/11/05#a3100
PHP Meeting in Paris
The French PHP User Group AFUP association is proud
to announce the third annual PHP meeting in Paris, on
November 26th and 27th, 2003
What is it?
Developers and managers will gather to meet Zeev
Suraski and other prominent community experts for
two days of conferences, packed with solutions and
advanced techniques
Get more information from: AFUP.org
php|a
PHP-GTK 1.0.0PHP-GTK announces the release of version 1.0.0.What is it?
PHP-GTK is an extension for PHP programming guage that implements language bindings for GTK+ toolkit It provides an object-oriented interface to GTK+ classes and functions and greatly simplifies writing client side cross-platform GUI applications
lan-The release announces: “PHP-GTK Version 1.0.0
is finally out after almost a year of being in stasis.This is probably the last major version that willwork with PHP 4 and Gtk+ 1.x There might bemore bugfixes, but no new features or upgradeswill be implemented PHP-GTK 2 is under develop-ment and will focus on PHP 5 and Gtk+ 2.x “Get more information from GTK.PHP.net
Direction|PHP
NEXEN.NET, leading portal for PHP/MySQL form in French, and php|architect, the Magazinefor PHP Professionals, have announced the imme-diate availability of DIRECTION|PHP, the Frenchmonthly magazine for PHP/MySQL professionals
plat-”The French PHP community is among thelargest and the most advanced in the world.”, saysDamien Seguy, editor-in-chief of Direction|PHP “
It needed a resource of expert knowledge and depth coverage of the industry Naturally, that led
in-us to partner with php|architect “
php|architect provides a monthly technicalresource for PHP professionals in the English mar-ket that includes in-depth articles, news, editorialcomment, and product and book reviews.Direction|PHP is focused tightly on covering Frenchnews, and licenses part of its content fromphp|architect
” Most technical knowledge is available inEnglish, even if its authors are not native Englishspeakers I believe Direction|PHP will create oppor-tunities for both French authors and companies tostep up to the plate and shine “, adds DamienSeguy
Get more information about Direction|PHP, visittheir homepage
Trang 10What is overloading?
Overloading is an important feature of most Object
Oriented Programming (OOP) languages like Java and
C++ In these languages, overloading allows the
pro-grammer to declare many methods or properties with
the same name Which one will be used when a call to
that function name is made depends on the type
(inte-ger, string, etc.) and the number of arguments passed
to the method
If you aren’t too familiar with OO languages, maybe
a very basic example in Java will help you out Take a
look at Listing 1
When the Java Virtual Machine finds a call to method
hheelllloo(()) of class Greet in this code, it will choose the
right method depending on the number of arguments
Of course, if we try to do this in PHP, all we will obtain
is a fatal error, like so:
Fatal Error: Cannot redeclare hello()
For a strongly-typed language, overloading is
impor-tant because it allows methods to behave in different
ways depending on the number and type of the
argu-ments received If we overload the constructor of a
class, we can obtain different objects depending on the
number and type of parameters passed
Overloading is one of the most useful peculiarities of
OO languages Unfortunately (at least, in my humble
opinion), PHP wasn’t born to be object-oriented OOP
is only really supported since PHP4, but still in quite a
poor way Thankfully, many improvements are being
introduced, and PHP 5 will finally provide great OOP
support One of these improvements is the overloadingextension Although this extension differs from the Javaversion of overloading, we’ll show how to use it to sim-ulate that overloading in PHP
What is overloading in PHP?
The “Object property and method call overloading”extension was introduced as a built-in, experimentalextension in PHP 4.3.0 It is supposed to become sta-ble in PHP 5
Its purpose is something different from the ing present in most object-oriented languages In fact it
Code Directory: object-overloadingREQUIREMENTS
class Greet { hello() { System.out.println(“Hello World”);
}
hello(string name) { System.out.println(“Hello “ + name);
Trang 11doesn’t even allow you to redeclare a method Instead,
its purpose is to allow you to use methods (and
proper-ties) which haven’t ever been declared inside the class
It does this by offering up three special methods that
will be executed when an attempt is made to access a
method or property that doesn’t exist These “magic”
methods are listed below
ggeett(()) : called when trying to use the value of
undefined properties
sseett(()) : called when trying to set the value of
undefined properties
ccaallll(()) : called when accessing undefined methods.
The most useful of these three methods to us is
ccaallll(()), since you’ve always been “allowed” to set and
get undefined properties in PHP 4 Among other
things, ccaallll(())allows us to execute built-in PHP
func-tions or user-defined funcfunc-tions as if they were actually
methods of the class
Overloading properties: ggeett(()) and
The property_name parameter is the name of the
undefined property being accessed, and the
return_value parameter is the value we will set inside
the function return_value should be passed by
refer-ence (using the special character “&”) to allow ggeett(())
to set the value Listing 2 shows how the ggeett(())
method works
First, we set the $$ggrreeeettproperty This is the only
prop-erty of class TryGet that we can access without
over-loading the class
Next, we have to fill in the ggeett(()) method with the
logic to determine what value ($$PPrrooppVVaalluuee) should be
returned for an undefined property ($$PPrrooppNNaammee) In this
case we set $$PPrrooppVVaalluuee to an error message
(“$PropName isn’t defined”), but we could also set it toFALSE, to zero, to a blank string, or to whatever makessense
Finally, we return TRUE from ggeett(()) This is becauseall of the “magic” methods should only return TRUE orFALSE This tells the parser whether the access was suc-cessful—returning FALSE will make the parser display anotice (“Notice: Undefined property”)
Before we can test this class, we must overload itusing the oovveerrllooaadd(())function
void overload(string ClassName)
Lastly, we try to print a defined property ($$ggrreeeett) andtwo undefined ones ($$ffoooo and $$bbaarr) The output is asfollows:
To set an undefined property we must use sseett(())
boolean set([string property_name], [mixed
value_to_assign])
This “magic” method must be used together with
ggeett(()) in order to work—setting a property withoutbeing able to get it is useless Have a look at Listing 3for an example
The sseett(())method stores the value of the undefinedproperty that the user tried to set into an associativearray ($$eelleemm), and then returns TRUE Like for ggeett(()),returning FALSE will cause a notice
Next, we put an if-else control in method ggeett(()) Ifthe undefined property is stored in the $$eelleemmarray, we’llset $$PPrrooppVVaalluueeto that value, otherwise set the value toour error message Finally, we return TRUE Note that
we could return FALSE instead of setting the property toour error message—in that case we could only get theproperties we’ve set (trying to get undefined propertieswe’ve never set would cause a notice)
Let’s test it out After having overloaded the class, weset an undefined property ($$ffoooo) to 3.14 Next, we get
$$ffooooand print it Finally, we try to get and print
anoth-er undefined propanoth-erty ($$bbaarr) we haven’t ever set Theoutput is shown below:
3.14 bar isn’t defined
The first value echoed is the one we’ve just set, whilethe other is the error message we decided to display
Overloading methods: ccaallll(())
ccaallll(()) is by far the most interesting feature of loading in PHP, allowing you to call undefined methods
9 $PropValue = “$PropName isn’t defined <br/>” ;
// Sets the value
14 overload ( ‘TryGet’ ); // Overloads the class
15 $overloaded = new TryGet ();
16 echo $overloaded -> greet ; // Prints the defined var
17 echo $overloaded -> foo ; // Prints an undefined one
18 echo $overloaded -> bar ; // Prints another undefined one
19
20 ?>
LISTING 2
Trang 12It requires three arguments: the name of the method to
call, an array containing the arguments, and the return
value (which is passed by reference) The syntax for
ccaallll(())is as follows:
boolean call([string method_name], [array
arguments], [mixed return_value])
In dealing with ggeett(()), we decided to return an error
message; with ccaallll(()) we can’t do anything similar
Instead, we will look for the undefined method that was
called, and execute it—there may be a function or a
method of another class which has the same name as
the one called This “magic” method can also returnTRUE or FALSE In fact, in the next example we’ll returnFALSE if the function method isn’t in the array whichcontains the ones allowed to be executed Just remem-ber that returning FALSE will cause a warning instead of
a notice Listing 4 shows an example of how to use
ccaallll(()).Outside of our class we declare function ggrreeeett(()); we’llneed it to demonstrate that ccaallll(()) also works withuser-defined functions Inside the class we’ve left theconstructor empty, and declared ccaallll(())
Our ccaallll(())function sets up an array ($$aacccceepptt) where
we store the name of the functions we will accept asmethods of this class If the method called is defined inthe $$aacccceepptt array, we’ll call the specified function, pass
in the parameter as an array element, and return TRUE
If the method is not defined in the array, we’ll returnFALSE (a warning) It’s best to allow only a few functions
to be called as a method (just the ones you need)
Now we can test it out After having overloaded theclass, we try to call three methods: method ggrreeeett(()), thePHP function ssqqrrtt(()), and the PHP function lloogg(()), echo-ing each value returned The output is shown below:
Hi John!
4 Warning: Call to undefined method trycall::log()
Notice that we called a predefined PHP function, butgot a warning This is because we decided not toaccept lloogg(())as a valid method to our class Also noticethat in ccaallll(()) we had to pass the parameter as anarray element ($$FFuunnccAArrgg[[00]]) That’s a problem, since itmeans we can only call one-argument functions! To fixthis we can use the ccaallll uusseerr ffuunncc aarrrraayy(())PHP function.Its syntax is as follows:
mixed call_user_func_array (callback function[,
13 if (isset( $this -> elem [ $PropName ])) // If the prop is in $elem
14 $PropValue = $this -> elem [ $PropName ]; // Assigns the value in the array
22 overload ( ‘TrySet’ ); // Overloads the class
23 $overloaded = new TrySet ();
24 $overloaded -> foo = 3.14 ; // Sets an undefined property
25 echo $overloaded -> foo “<br/>” ; // And prints it
26 echo $overloaded -> bar ; // Prints an undefined and never set property
15 $this -> accept = array( “greet” , “sqrt” );
// Array of valid functions
16 if( in_array ( $FuncName , $this -> accept )):
// If a valid function is called
17 $RetValue = $FuncName ( $FuncArg [ ]);
// Executes the function
25 overload ( ‘TryCall’ ); // Overloads the class
26 $overloaded = new TryCall ();
27 echo $overloaded -> greet ( “John” );
// Calls greet() as method
28 echo $overloaded -> sqrt ( 16 ); // Calls sqrt() as method
29 echo $overloaded -> log ( 10 ); // Calls log() as method
30
31 ?>
LISTING 4
Trang 13ccaallll uusseerr ffuunncc aarrrraayy(()) allows us to call functions and
methods, passing the parameters as an array Since they
are passed into ccaallll(())as an array, we can now easily
call any function we want As an example, have a look
at Listing 5
Here, we set up our class and use
ccaallll uusseerr ffuunncc aarrrraayy(())to call the function and pass the
parameter array to it PHP will automatically execute
the function, as long as the script has called the method
with the right number of parameters
Note that being able to call any function as a method
is not so good It isn’t necessarily a security issue, since
the call is done by a script of ours, and not an external
user, but it can certainly cause some confusion The
out-put of Listing 5 is shown below
12
256
11111010
As we said, we can use a regular function as a method
of our class; but we can also call a method of another
class as one of ours, like so:
$retVal = call_user_func_array( array (
new ClassName(), $MethName),
$MethParam);
That means that by using overloading, we can also
easily extend a class without using the extension
mech-anism
Now it’s time to write a class which does something
useful with the overloading extension
Overloading methods: A practice
example
For our example, we will create a class which manages
database operation using the overloading extension
The database chosen is MySQL, a widely-used
open-source database, and we will be executing queries on
the following sample table:
CREATE TABLE names (
id TINYINT UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR( 30 ) NOT NULL)
The purpose of our class is to allow us to use OOP
techniques to perform the most common database
operations, such as:
• Connecting to MySQL and closing the
con-nection
• Selecting, creating and dropping databases
• Sending queries and counting the rows
affected
• Fetching the result data
The code for this example is shown in Listing 6
Since an open connection to MySQL is always
need-ed to perform any operation, we can put
mysql_connect() in the constructor of the class, andstore the resource link returned in a class property($$lliinnkk) In ccaallll(()) we decide which functions we’llaccept, and we store them in two array properties Thereason for two arrays is that some MySQL functionsrequire the connection link as the last parameter, whileothers don’t We will automatically add the link to theparameters of the ones which need it
We put the functions which need the link in $$aacccceepptt ll,and the ones that don’t in $$aacccceepptt They are both asso-ciative arrays—the key is the method name and thevalue is the MySQL function name Note that the prefix
“mysql_”, which each function should have, is omittedfor simplicity and will be added when we execute thecall
Now comes the most important part of our class It’sall contained in an if-elseif-else block
• If the function called as a method is validand requires the connection link, we will add
$$lliinnkkto the parameters array, call the tion, and return TRUE
func-• If the function is valid, but doesn’t require aconnection link, we will simply call it andreturn TRUE
• If the function is not valid, we will returnFALSE (the script will return a warning)After having called a MySQL function, the script willcheck if it has been successful If it hasn’t, a MySQLerror message obtained by mysql_error()will be dis-played
Now our class is complete—we only have to overloadand test it We create a new object, passing the connec-tion parameters to the constructor, and then select thedatabase Next, we execute a SELECT query on the
1 <?php 2
9 $RetValue = call_user_func_array ( $FuncName , $FuncArg );
// Calls the function
14 overload ( ‘TryCallParam’ ); // Overloads the class
15 $overloaded = new TryCallParam ();
16 echo $overloaded -> sqrt ( 144 ) “<br/>” ;
17 echo $overloaded -> pow ( , 8 ) “<br/>” ;
18 echo $overloaded -> base_convert ( “FA” , 16 , 2 );
19
20 ?>
LISTING 5
Trang 14table shown above, fetching and echoing the result.
Finally, we close the connection
All these operations are performed in OOP We wrote
less code than with procedural coding, and the code
looks clearer We performed only a few of the
opera-tions allowed, but you can be sure that the others work
just as well
This example has shown how we can use the
over-loading extension to organize our code in an
object-ori-ented manner, and simplify it Of course the class can
be saved in an external file, and included to make the
code even clearer You can use overloading to group
any set of functions into a class; for instance, you could
create a CURL or Output Buffering class
Creating Java-like overloading in PHP
At the beginning of this article we explained the sic” meaning of overloading We also explained that inPHP, we can’t redeclare a method You might haveguessed that ccaallll(()), though, can help us to do some-thing similar It won’t be as elegant as it could be in Javabut it will work!
“clas-Imagine we have a method on which we want toallow overloading What we have to do is to preparedifferent methods using the original method’s nameconcatenated with the number of arguments passed to
10 function MySQL ( $server , $user , $pass )
11 { // The constructor opens the connection
12 $this -> link = mysql_connect ( $server , $user , $pass )
20 /* Accepted funcs that need a resource link */
21 $this -> accept_l = array( “close” => “close” , // mysql_close()
22 “db” => “select_db” , // mysql_select_db()
23 “newdb” => “create_db” , // mysql_create_db()
24 “dropdb” => “drop_db” , // mysql_drop_db()
25 “query” => “query” , // mysql_query()
27
28 /* Accepted func.s that don’t need a resource link */
29 $this -> accept = array( “arows” => “affected_rows” , // mysql_affected_rows()
30 “nrows” => “num_rows” , // mysql_num_rows()
31 “afetch” => “fetch_array” , // mysql_fetch_array()
32 “rfetch” => “fetch_row” , // mysql_fetch_row()
33 “ofetch” => “fetch_object” , // mysql_fetch_object()
35
36 if(isset( $this -> accept_l [ $FuncName ]))
37 { // If the function requires $link
38 $FuncArg [] = $this -> link ; // Adds $link to the parameters of the array
39 $RetValue = call_user_func_array ( “mysql_” $this -> accept_l [ $FuncName ], $FuncArg )
40 or die( mysql_error ());
41 return TRUE ;
42
43 }elseif(isset( $this -> accept [ $FuncName ])){
44 /* If the function doesn’t require $link calls the function */
45 $RetValue = call_user_func_array ( “mysql_” $this -> accept [ $FuncName ], $FuncArg )
46 or die( mysql_error ());
47 return TRUE ;
48 }else // If the function isn’t accepted
49 return FALSE ; // Returns an error
58 $db = new MySQL ( ‘localhost’ , ‘user’ , ‘pass’ ); // Creates the object
59 $db -> db ( “mydb” ); // Selects the db
60 $res = $db -> query ( “SELECT * FROM names” ); // Executes the query
61
62 /* Fetchs and prints the data */
63 while( ( $data = $db -> afetch ( $res , MYSQL_ASSOC )) !== FALSE )
64 echo $data [ “id” ] ”: ” $data [ “name” ] ”<br/>” ;
Trang 15it This would look something like:
“method name” “argument number”
But –and this is important– we mustn’t declare a
method called “method name” If we do, ccaallll(())
won’t be able to manage the call to our method (since
it wouldn’t be undefined) Listing 7 shows how this all
works
In method ccaallll(())we first check the number of the
arguments of the undefined method call Depending
on that, we execute the “right” method We’ve named
the “right” methods as methname0, methname1,
methname2, etc., depending on how many arguments
they need When we call mmeetthhnnaammee(()), the parser will
exe-cute ccaallll(()), which will determine the right method by
appending to “methname” the number of arguments
passed
Note that the method to call is indicated as
array(&$this, $FuncName.$NumArgs)
That’s because it isn’t an external function, but a
method of the current object ($$tthhiiss) After method
ccaallll(()) we declare all the methods we may need to
use Now we can overload the class, and try to call themethods The output from Listing 7 will be:
Hello World!
Hello Peter!
Hello John! Greetings from London!
16 81
This feature can be particularly useful if we want tooverload the constructor, which would allow us to builddifferent objects depending on the number of argu-ments passed!
Automatically overload a class
As we’ve seen, to overload a class we have to write theline:
overload(“ClassName”);
This is tedious, especially if the class has been created
to be overloaded In PHP 5 this is not supposed to beneeded, but now it currently is, we might want to fix it
If we want to automatically overload a class, we onlyhave to add this line to the constructor:
overload(get_class($this));
That means that when we build a new object the structor automatically enables overloading support.This is another detail which may help us to keep ourcode clear
con-ConclusionThe overloading extension has got great potential Ofcourse you can write any application you need withoutusing it (as you don’t need to use OOP), but it can pro-vide an intuitive and elegant solution to some prob-lems; for instance, it can help you to group a bunch ofprocedural functions (user-defined or built-in) into aclass library, or to create easily-extensible classes with-out using the extension mechanism
Remember that the overloading extension is stillexperimental, and the interface and inner workingsmay still change drastically, but I expect that it willbecome a very powerful coding technique
I hope this article has helped you to find out howoverloading can make your coding easier If you haveany questions about it, you can look at the PHP on-linemanual (which unfortunately doesn’t treat this topicvery well), ask on the php|architect forum, or mail me
9 $NumArgs = count ( $FuncArg ); // Counts the number of
arguments to find the right meth
10 $RetValue = call_user_func_array (array(& $this ,
$FuncName $NumArgs ), $FuncArg );
40 overload ( ‘JavaOverLoad’ ); // Overloads the class
41 $overloaded = new JavaOverLoad ();
42 $overloaded -> greet ();
43 $overloaded -> greet ( “Peter” );
44 $overloaded -> greet ( “John” , “London” );
45 $overloaded -> power ( ); // It should return 2^4
46 $overloaded -> power ( , 4 ); // It should return 3^4
47
48 ?>
LISTING 7
Click HERE To Discuss This Article http://forums.phparch.com/57
Alessandro Sfondrini is a young Italian PHP programmer from Como He has already written some on-line PHP tutorials and published scripts on most important Italian web portals You can contact him at
giu_ale2@hotmail.com
Trang 16Why is it so important?
As you browse through Sourceforge
(www.sourceforge.net) in search of the open-source
software that you need, you’ll notice that all of the
proj-ects offer you their source through CVS If you are not
familiar with Concurrent Versions System (CVS), the first
question is usually: “Why don’t they just pack the files
and distribute it as an archive?”
CVS has multiple uses in software development, so
let’s take a few different angles and try to find out how
you could benefit from it
Suppose, for a start, that you want to start an open
source project You want to have a lot of developers
work together from all around the world So the first
question is: “How can we all work on the same code
base and keep that repository consistent?”
Let’s say that you assign two developers to work on
the same file (e.g system/lib/classes/customer.php) You
give them both accounts on the development server so
that they can copy files to and from their local
environ-ment It all sounds good at the start, but sooner or later
you’ll get into the following situation Both developers
get a copy of the file in order to work on different
meth-ods After a while the first developer puts a changed file
on the server, but he doesn’t remember to notify the
second developer that he should collect a new version
of the file When the second developer is done coding,
he puts his version of the file back on the server,
over-writing the work of the first developer
OK, so you can say that communication within the
team should be organized in such a manner as to help
avoid this situation, and you’re right But in this
exam-ple we assumed only two developers and one file; ine how would it be when your team expands toinclude tens or hundreds of developers and resources.You shouldn’t have to waste your time and energykeeping track of concurrent changes in the source—letsoftware do the dirty work
imag-The best way is to install a CVS server and make itpublic (so everyone can get the latest version of thesource using an anonymous account) Then assignaccounts with commit privileges to your developers sothey can contribute their code to the repository Yourproblem is solved Every developer has to pull the latestchanges from the repository before he can start work-ing, and after the work is done he asks the server to syn-chronize the repository with his changes If someoneelse has committed changes to the same files in themeantime, the developer is given the opportunity toresolve any conflicts This way we are sure that thesource repository is always consistent, and that no codecan mysteriously vanish
If you are working in the local environment whereyour development team is changing the code directly
on the server, you could suppose that this article has novalue for you—but don’t jump to conclusions CVS is
Introduction to Version Control with CVS
PHP: 4.xOS: AnyApplications: N/ACode: N/ACode Directory: N/AREQUIREMENTS
by Dejan Bosanac
Trang 17much more then just keeping the code consistent It
also offers a total history of all code changes Have you
ever found yourself in the following situation? You learn
that you have to make huge changes to some portion
of the code You start working, and after a week you
find yourself thinking that you would like to have the
original code back because you realized that there’s a
much easier way to do it But now you don’t have that
code, and it will take you a lot of time to get it back to
that state (if it’s even possible in the first place) With
CVS, situations like this are not as horrific You can just
pull the desired code version (or date) from the
reposi-tory, and start all over again
I’ll mention another benefit of CVS, and I’m sure that
once you start using it, you’ll find that you can’t live
without it Imagine the following You find yourself
doing pretty well with your project You have a large
number of clients that have purchased different
ver-sions of the software For some of them you had to
make a few customisations, and in some versions
differ-ent bugs have been found All of a sudden you’re in a
no-win situation again You could easily get lost with
which code base should be modified or fixed, and you
could end up delivering the wrong update package to
the customer With CVS you can easily organize your
code in versions and branches, and let the software
take care of that All you need to do is to checkout the
right branch and version of the code, modify it, check
it in again, and update client’s distribution Piece of
cake, isn’t it!
Learning by example
Now we’ll go through all of the everyday steps in order
to get the picture on how to use basic CVS commands
Assume that we started to work on an e-commerce
software project in PHP On the development server, the
project is in the /home/web/e-commerce folder This is
known as the “working directory” in CVS terminology
Let’s imagine that we have only three files for now This
will make our examples clear, but still descriptive
enough
index.php
login_form.php
login.php
Before we add our project to CVS, CVS should be
properly installed and configured on the desired server
If you are a Unix/Linux user, then you will probably
have it already on your machine If this is not the case,
get the source and all the necessary documentation
from the official CVS site (http://www.cvshome.org),
and follow the instructions regarding your particular
system environment Once you have installed CVS, you
can start using it as a client for other repositories If you
want to use it as a source repository for yourself, you
should first initialize the repository You can do this
using the init command
$ cvs -d /usr/local/cvs init
This creates a repository in the /usr/local/cvs tory
direc-We’re now ready to use CVS in the local environment
In later sections some other interesting configurationissues for remote servers will be introduced
When using CVS as a client, we need to tell the clientprogram where the code repository is We can do thiseither by using the “-d” switch directly in the commandline (e.g cvs -d /usr/local/cvs/ llooggiinn) or by settingthe $$CCVVSSRROOOOTTenvironment variable, like so:
$ export CVSROOT=/usr/local/cvs)
The first thing we should do is to import our project
into CVS for tracking
$ cd /home/web/e-commerce
$ cvs import -m “Imported source” e-commerce “OurCompany” start
This command tells CVS that we want to start ing the source in this folder in the repository under the
track-name “e-commerce” (module track-name) The “-m” switch
is optional, and it allows us to add an appropriate ment for this action If it is omitted, CVS will start aneditor to allow us to enter the comment CVS keepstrack of all the comments that are entered with eachchange so that we can have a complete history of allthe important notes for the resource and the project as
a whole This switch is also used in some other mands, as we will see in a moment
com-In the above command, “OurCompany” represents
what’s known as the vendor tag “start” is a release
tag These tags may have no role in this context, but
because CVS needs them, they must be present
Now we can check what have we done We will
checkout the project from the repository to be sure
that everything is fine, and start working on the sourcethat is under CVS control First, we should move thecurrent project to a temporary folder
$ diff -r /home/web/e-commerce /home/web/e-commerce.orig Only in e-commerce: CVS
You’ll see that the files are exactly the same Maybenow is a good time to remove the original source fold-
er, just to be sure that we don’t accidentally edit it
Trang 18instead of the files that are under CVS Before you do
this, you may want to consider backing it up
some-where, just in case
$ rm -r /home/web/e-commerce.orig
If you list the working directory now, you would see
that beside the regular project files we have a “CVS”
directory It is the system directory used by CVS, and
under normal conditions you should ignore it It is used
to keep information such as which repository is in use,
what files and versions have been checked out, as well
as all the other useful data about the current working
directory’s state We will talk about this folder in the
next section, but unless you know what you are doing,
keep away from it or you could damage the tracking
process CVS directories exist in every subdirectory of
your project that has been checked out
We said that each time you start working on the code,
you should ask CVS if any changes have occurred in the
files that matter to your work You can do this by using
the update command.
$ cvs -qn update
You won’t get anything in this example because
we’ve just checked the project out, and all the files are
up-to-date We will see how this command works later
in the article The “-q” switch tells CVS to be “quiet”
and print only important information This is an
option-al switch, but it is very useful if a large number of files
have been changed The “-n” switch tells CVS not to
do any real updates, but just to show us what needs to
be done If we omit it, all the files that are shown as not
up-to-date would be updated according to the changes
that are in the repository If you agree that all the files
should be updated, just repeat that last command
with-out the “-n” switch
$ cvs -q update
You can update just the files that you are interested
in, rather than getting all the changes This can be done
by specifying the files of interest at the end of the
com-mand line
$ cvs -q update index.php login.php
Now we are ready to start working on our source
Lets say that our index.phpwas like this:
<?
// TODO
?>
We will modify it so that we can show how CVS reacts
to these changes, and describe further steps Let’s add
some code to the file
<?
echo “E-commerce 1.0 - under construction”;
?>
It’s not a big progress in the project, but it should be
enough for now If we try to see the difference betweenworking copy and the repository, we would get some-thing like this:
$ cvs -qn update
M index.php
A status of “M” means “locally modified” It meansthat the local copy of the file has been changed andthat those changes have not yet been committed to therepository This would seem to be the exact case withour index.php Some other possible statuses are:
U - “update needed” - means that the local file
version is not accurate and that a newer sion of the file has been committed to therepository
ver-P - “patch needed” - means that the local file
version is not accurate and that file has to bepatched with one in the repository This isusually the case when the changes in the fileare not big and CVS could just patch the filewith the current version It has practically thesame meaning as a status of “U”
C - “conflict” - means that file could not be
patched (or updated) automatically We willsee a little bit later how to deal with the con-flicts
You can see the differences between the working and
repository versions with the diff command.
$ cvs diff index.php Index: index.php
==================================================
RCS file: /home/office/cvsroot/test/index.php,v retrieving revision 1.1.1.1
diff -r1.1.1.1 index.php 2c2
< // TODO
—-> echo “E-commerce 1.0 - under construction”;
This line will give us the exact changes between theworking and repository versions If you look at it care-fully, you can see that in the current version the text “// TODO” has been taken out, while the text “eecchhoo ““EE ccoomm mmeerrccee 11 00 uunnddeerr ccoonnssttrruuccttiioonn””;;” was introduced in linetwo
The next thing we want to do is to commit our work
to the repository so other developers can use it We canaccomplish this by doing the following:
$ cvs commit -m “Welcome note added”
Checking in index.php;
/usr/local/cvs/e-commerce/index.php,v <— index.php new revision: 1.2; previous revision: 1.1
done
Of course, we can also commit on a file basis, just aswith the update command This is useful in situationswhen you have finished one piece of functionality andstarted another You need to submit only the changes
Trang 19made to some files, because other files are still
unfin-ished When you want to do this, just append the
rele-vant file names to the command
$ cvs commit -m “Welcome note added” index.php
We talked about the “-m” switch with the import
command, and it serves the same purpose here:
speci-fying the comment for the action
If you check for changes now, you’ll see that
every-thing is up-to-date and it’s time to move on with our
project Imagine that we add some new scripts to our
project; of course we need to add them to CVS
reposi-tory, as well First we have to create a new file, for
example logout.php You can do it in your favourite
edi-tor or integrated development environment If you now
check CVS for changes, you will see something like this
$ cvs -qn update
? logout.php
Our new script is there but with the unusual status
“?” That means that CVS has no information on this
file, and that the add command should be used.
$ cvs add logout.php
cvs add: scheduling file `logout.php’ for addition
cvs add: use ‘cvs commit’ to add this file permanently
If you now check for changes, you’ll see the “A”
sta-tus, which means that file has been scheduled for
adding, but should be committed in order to finish the
Now the process is completed
Of course, one of the common CVS operations is the
removal of files from the repository Like all of the other
operations, this is quite easy to do First you have to
remove the file from the working directory
$ rm logout.php
Then use the CVS remove command to remove it
from the repository
$ cvs remove logout.php
cvs remove: scheduling `logout.php’ for removal
cvs remove: use ‘cvs commit’ to remove this file permanently
$cvs -qn update
R logout.php
Now, you can see that file has been marked with an
“R”, which means that the file is marked for deletion,
but we need to call the commit command to complete
File: index.php Status: Up-to-date
Working revision: 1.2 Tue Sep 2 20:34:20 2003 Repository revision: 1.2 /usr/local/cvs/e- commerce/index.php,v
Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none)
We were talking about conflicts before, so now wewill intentionally create one and see how to deal with it.For that purpose we will need another working directo-ry
$ cd /home/web
$ mkdir e-commerce_conflict
$ cvs checkout -d e-commerce_conflict e-commerce
Now we shall modify the index.php in our original
e-commercedirectory to be like this:
retrieving revision 1.2 Merging differences between 1.1 and 1.2 into index.php rcsmerge: warning: conflicts during merge
cvs update: conflicts found in index.php
C index.php
The index.phpnow looks like this
<?
<<<<<<< index.php echo “E-commerce 1.0 - under construction”.“-debug”;
Trang 20remove the local copy and start all over.
The commands introduced above cover the most
common tasks that you as a developer will perform with
CVS, and often it is all you need to know
How does it work?
Let’s turn our focus now to a few advanced CVS topics,
and see how it works “under the hood” This can be
very useful in cases where you experience difficulty
working with CVS
We already mentioned the CVS directories that are
placed in the working subdirectories These directories
keep track of the state of the working directory with
regards to a certain repository The CVS directories can
contain several files, but here we’ll examine only the
ones that are most important for you as a developer
The Root file contains information about the current
CVS “root”, which is the directory where the CVS
repos-itory lives This will likely be the directory that we chose
in CVS initialization - /usr/local/cvs
The Repositoryfile contains the directory for our
proj-ect in the CVS repository Remember, one CVS
reposito-ry can be used for several projects This could be an
absolute or relative path, so our Repository file could
contain e-commerceor /usr/local/cvs/e-commerce
The Entriesfile lists the files and directories in the
cur-rent working directory that are under CVS control It is
a plain text file that contains a file or subdirectory on
each line You can tell what kind of entry each line is by
examining the first character of that line If the first
character is “/”, then it is a file entry in the following
format:
/name/revision/timestamp[+conflict]/options/tagdate
• nameis the name of the file within the
direc-tory
• revisionis the version of the file in the
work-ing directory It could also be a zero (0) for
newly-added files or a dash followed by a
revision number (-1.1) for removed files
• timestampis a universal time (UT) timestamp
that shows when the file was created by
CVS If it differs from the file’s modification
time, the file has been changed If you want
to force the file to always be considered as
modified, you could put a different string
here (e.g “Always modified”), since CVS
always does just a simple string comparison
• conflictindicates that there was a conflict
during the file update, and if the file
modifi-cation time is the same as the timestamp it
means that the developer hasn’t resolved the
conflict yet
• optionsand tagdate are connected with sion numbers and sticky tags, which are notgoing to be covered by this article
revi-An example file entry could look like this:
/index.php/1.6/Thu Sep 25 23:01:21 2003+conflict//
The format for directory entries in the Entries file is:
D/name/filler1/filler2/filler3/filler4
• nameis the name of the subdirectory
• fillerfields are left for future enhancement
An example entry for the system subfolder would be:D/system////
Now that you know how the working directory CVSdirectories are organized, we will briefly go through therepository organization, which will give us an idea ofhow the other side works The repository is just a direc-tory on your server (or a remote server, as we will seelater) Project files are stored in the repository withnames that are the same as the working names with
“,v” appended to the end These files are known as
his-tory files or RCS files They contain enough
informa-tion to recreate any version of the file These files alsocontain all of the comments that were entered in theimport and commit process (remember the “-m”switch) This way a complete log history of each filecan be generated (including the usernames of the com-mitters)
Sometimes CVS stores RCS files in the Attic
subdirectory If we suppose that our CVSROOT
is /usr/local/cvs, then it is normal that the history
file for the index.phpin the e-commerceproject would
be /usr/local/cvs/e-commerce/index.php,v If the file
was removed, it is stored in the Attic
subfolder (in our example, merce/Attic/index.php,v) As an aside, if you fol-lowed all of the operations in the first part of thisarticle, and you are able to cd into the CVSrepository, you should find logout.php in the Attic
/usr/local/cvs/e-com-directory
In the repository you will also find the CVSROOT
directory This directory contains administrative files.For a complete list of all possible administrative files andtheir organization, you should check the CVS documen-
tation Here we will mention only the modules file, as
that is the most important one for us
The modules file can be used to create aliases and togroup project resources into logical modules It is aplain text file with one line for every module or alias.Lines can be continued over more than one line, byappending the backslash (“\”) character to the end ofeach line
Aliases have the following syntax:
Trang 21alias_name –a what_to_alias
For example, let’s go back to our e-commercedirectory
from earlier If we don’t like typing “e-commerce” all
the time, we can define an alias
ecom -a e-commerce
This would make the result of the following two
com-mands the same
$ cvs checkout e-commerce
$ cvs checkout ecom
Modules are defined as:
module_name [options] directory [files ]
for example
ecom e-commerce
This way when you do a checkout you will get an ecom
directory, instead of e-commerce, although the files will be
the same
$ cvs checkout ecom
By specifying a filename behind the directory name in
the module file, you can include only those files in the
module, rather than the whole directory This might be
useful, for example, if your project is split into logical
sub-systems
ecom e-commerce login.php
If you now do the checkout, you will only get the
file(s) you specified
A module definition can include other modules If you
want to do that you should add an ampersand (“&”)
sign before the module name
ecom &e-commerce &other_module
Administrative files are stored in the CVSROOT
direc-tory in RCS format, just like regular project files, but a
working copy of each file should also be present So for
the modulesfile, you should find both modules,vand
mod-ulesthere You can freely edit any of the administrative
files the same way you edit the project file All you have
to do is to check it out, change it, and commit it back
to the repository
$ cvs checkout CVSROOT
$ cd CVSROOT
[edit modules file]
$ cvs commit -m “CMS module added” modules
Of course, you should be careful with this process as
it could affect general CVS behaviour Only modify
administrative files if you know exactly what you are
doing
Adapt it to your organization’s needs
Now that we know all the basic things about CVS, we
can go a little further and see how you can adapt it toyour specific organization’s needs
The first thing you should think about is the location
of the CVS server All of our previous examples assumedthat the CVS repository is on the same server as theworking directory This is acceptable in some cases, butnot always If we go back to the example of the open-source project with developers spread all over theworld, this configuration would not be very useful.What we need is a CVS server that is publicly availablevia the Internet for developers to use Fortunately, usingremote repositories is as easy as using local ones All youhave to do is to use the following format for your CVS-ROOT (specified either with “-d” switch or in an envi-ronment variable as we saw above):
:method:user@hostname:path_to_repository
method indicates what authentication method is in use
You can connect to CVS using rsh, kerberos or
pass-word (pserver) authentication In this article we will
focus on the password authentication; for more details
on other connection methods you should consult theCVS documentation Connecting with passwordauthentication is useful in the situation when rsh orKerberos are not available for some reason First of allyou should set up your inetd to correctly receive con-nections for CVS on the appropriate port (2401 bydefault) and to execute the “cvs” command Usually,adding the following line in /etc/inetd.conf should besufficient
2401 stream tcp nowait root /usr/local/bin/cvs cvs —allow-root=/usr/local/cvs pserver
Separate CVS and system account passwords can beintroduced, which is very useful because pserverauthentication sends plain-text passwords through thenetwork, meaning that system accounts could be com-promised
Setting up a separate CVS account password is doneusing the $CVSROOT/CVSROOT/passwdfile This is a plain textfile that can be created and modified with any text edi-tor It’s in the same format as the /etc/passwdfile except
it has only three fields: cvs_username, password,optional_system_username The optional usernameallows you to map your desired cvs username with theappropriate system account This means that if youauthenticate as cvs_username, you would end up usingthe CVS server under the optional_system_username sys-tem identity
Passwords are encrypted with the standard Unix
ccrryypptt(())function so it is possible to copy and paste words from the /etc/passwdfile In this case you shouldconsider protecting the $CVSROOT/CVSROOTdirectory withthe same privileges as the /etc directory to preventmalicious users form compromising your CVS server
pass-If CVS can’t find a username or the passwd file it willtry system user look-up (system password file, LDAP,
Trang 22etc) in order to try to authenticate the user This feature
can be disabled by specifying a “no” value for the
SSyysstteemmAAuutthhvariable in the $CVSROOT/CVSROOT/configfile
On the client side, the user just has to use the cvs
command specifying the remote repository with the
pserver authentication method (either using “-d” or
storing it in the $$CCVVSSRROOOOTTvariable) When you are
access-ing the remote repository for the first time, you have to
login That is done using the login command, which
will prompt you to enter your password
$ cvs -d :pserver:dejanb@phparch.com:/usr/local/cvs login
Logging in to :pserver:dejanb@phparch.com:2401/usr/local/cvs
CVS password:
After logging in, your password will be stored in the
$HOME/.cvspass file The password is not stored in plain
form, but it is trivially encoded and could be easily
com-promised This is, along with sending passwords in the
plain-text form, the biggest security flaw of the pserver
method of CVS authentication The location of this
client password file can be changed by setting the
CCVVSS PPAASSSSFFIILLEEenvironment variable
Now we’ve solved the problem of remote access to
the project repository for developers, but that is not
enough What we want to do is ensure that everyone
can obtain the source of the project, but that only the
core developers can commit changes This can be done
by using an anonymous account with the pserver
authentication method An anonymous account can
be created by inclusion (a username is explicitly marked
as the read-only account) or by exclusion (username is
not on the list of users with write privileges) For this
purpose you use the readersand writersfiles in the
$CVS-ROOT/CVSROOTdirectory You can create and modify these
files (as well as the passwdfile) in the same way as we did
the modules file earlier In the readers file put all
user-names that you want explicitly to have a read-only
account, for example
anonymous
guest
In the writersfile you should explicitly declare all the
usernames that have write privileges, for example
dejanb
arno
All of these usernames must exist in the CVS passwdfile
or on the system The authentication method then goes
like this (once the user is authenticated):
• If the readersfile exists with that username
list-ed, then the user gets read-only access
• If the writersfile exists and there is no given
username there, then the user would get
read-only access again
• Otherwise, the user gets write access to the
repository
There could be a conflict situation, too If a usernameexists in both readers and writers files, that user getsread-only access
Now we have all that we need to start working on ourproject
BranchesCVS is not restricted to linear development You can
create branches of your source, which could be
valu-able for fixing bugs in previously-released versions ofyour project Let’s say that we have released version 1.0
of our e-commerce suite, and continued on to work onthe 1.1 release After a while, a client calls and reports abug in the code, but our repository has changed sincethat release and we don’t have an accurate version ofthe source to work on
Every branch has its own number Branch numbersconsist of an odd number of period-separated integers.The revision number of the file being branchedbecomes the branch number followed by a period and
an integer In Figure 1 we can see examples of the filerevision and branch numbers
It can be very useful if we make a branch of the code
after every project release Use the tag command with
the “-b” switch to name the branch
$ cvs tag -b e-commerce-1-0 cvs tag: Tagging
$ cd /home/web
$ cvs checkout -r e-commerce-1-0 e-commerce
After you made modifications you wanted, you cancommit it as before and changes will be applied in thedesired branch and not in the main developmentbranch If you want to get any changes that otherdevelopers made in the desired branch, you could usethe “-r” switch with the update command
$ cvs update -r e-commerce-1-0
There are many other possibilities with branching,
Trang 23such as merging branches back into the main
develop-ment branch, but they are outside the scope of this
arti-cle
CVS Tools
Until now, we only talked about the CVS server and
command-line client commands If you like to work in a
window-based, graphical environment and find
your-self uncomfortable with typing commands, there are lot
of solutions that you can use
Many modern integrated development environments
(IDE), for example, support CVS You could use Eclipse
(http://www.eclipse.org) with the PHP plug-in
(http://phpeclipse.sourceforge.net) and benefit from the
power of their integrated GUI for CVS access
It seems that the majority of script developers tend to
just use a good text editor for their development (no
matter whether they work in Windows or Unix
environ-ments), so we will focus on a few standalone
applica-tions that could make your client CVS tasks easier
Tortoise CVS (http://www.tortoisecvs.org/) is
Windows-based tool that allows you to
inte-grate basic CVS commands into Windows
Explorer After installation you can find extra
options on your right-click menu that allow you
to update, commit, or do anything you need
with your code See Figure 2
CVSGui (http://www.wincvs.org) is a set of GUI’savailable for the Windows, Macintosh, orUnix/Linux environments It’s a powerful appli-cation that uses the native look-and-feel ofyour operating system It contains a file brows-
er, a module browser, command line support,and many other advanced features that canhelp experienced users to automate their tasks
See Figure 3
Chora (http://www.horde.org/chora) is a PHPapplication that allows you powerful file data(authors, logs, differences) browsing and graph-ical branch representation
CVSweb
(http://www.freebsd.org/projects/cvsweb.html) - is asingle Perl script written originally for theFreeBSD project Over time it has earned greatpopularity among software developers Itenables you to browse a repository’s revisionhistory with a web
browser
Figure 3
Trang 24Further steps
If you’re planning a potentially large project, you’ll initely need a version control system, and you’re betteroff to do it from the start CVS is a proven tool for thejob, and has a huge resource base Many developersare familiar with it, reducing the need for extra training,and there are a plethora of tools out there for workingwith CVS, including source tree analysis
def-This article has only covered the tip of the icebergwith CVS and associated tools There’s much more tolearn, and you’ll find a ton of information on the web,
so check it out!
Figure 2
Click HERE To Discuss This Article http://forums.phparch.com/58
Dejan Bosanac works as a fulltime software developer for DNS Europe Ltd ( http://www.dnseurope.net ) on the Billing software system for ISP's In his spare time he also serves as a Lead Engineer at Noumenaut Software ( http://www.noumenaut.com ) on the online journaling project He holds
a Bachelor degree in Computer Science and currently is on the master studies in the same field.
FavorHosting.com offers reliable and cost effective web hosting
SETUP FEES WAIVED AND FIRST 30 DAYS FREE!
So if you're worried about an unreliable hosting provider who won't be around in another month, or available to answer your PHP specific support questions Contact us and we'll switch your information and servers to one of our reliable hosting facilities and you'll enjoy no installation fees plus your first month of service is free!*
Please visit http://www.favorhosting.com/phpa/
call 1-866-4FAVOR1 now for information.
- Strong support team
- Focused on developer needs
- Full Managed Backup Services Included Our support team consists of knowledgable and experienced professionals who understand the requirements of installing and supporting PHP based applications.
Trang 25W Wrriittee ffoorr uuss!!
Trang 26PHP-GTK is a PHP extension that provides an
object-oriented interface to the GTK+ toolkit GTK+ is a
multi-platform toolkit for creating graphical user
interfaces, or GUI’s PHP-GTK is an excellent tool for the
rapid development of stand-alone desktop applications
It gives you the opportunity to create these “real”
appli-cations in PHP, without having to bother with more
expensive development environments like Visual Basic
or Delphi
Another advantage, of course, is the multi-platform
possibility PHP with the PHP-GTK extension can be run
on several platforms, including Linux and Windows
98/NT/2000/XP; some have also reported it to work
under the new MacOS X
Before starting your quest throughout the PHP-GTK
world you may wish to brush up on PHP’s
object-orient-ed side, as this extension is heavily object-orientobject-orient-ed
Have a peek at http://www.php.net/oop and
http://www.php.net/language.references for a
refresher (or introduction)
Installation
Before we can get going with some actual coding,
you’ll need to install the PHP-GTK extension Start by
downloading the latest stable release from
http://gtk.php.net/download.php
For this article I used the 0.5.2a Windows and PHP
binary, which is probably the easiest way to get going
quickly The Windows installation is a 5 minute job
where you unzip the package and move some files
around Read the README.TXT file included in the
pack-age for the exact steps
Under Linux the install is a bit different, as there are
no officially released pre-compiled binaries Thismeans that you have to download the source and com-pile it on your own Again, information on how to goabout this can be found in the tarball
Your first PHP-GTK applicationHow else should we start than by writing a short “Helloworld” application? Let’s have a look at Listing 1, which
is actually a bit of an enhanced “Hello world” tion, since it includes some extra functionality to make
applica-it a lapplica-ittle more interesting
In order to work with the GTK functionality we firstneed to load the PHP-GTK extension We do thisdynamically at runtime using the dl() function Notethat it’s a bit different under *nix and Windows, sinceWindows uses .dllfiles and *nix uses .so files
Although we’re choosing to do it manually for clarity,
it is possible to load this extension automatically by ting it in your php.ini file along with the other PHPextensions Loading the extension manually, though, isless resource intensive when you use your PHP binaryfor things other than PHP-GTK
Code Directory: gtkREQUIREMENTS
Trang 27Getting back to Listing 1 we then have the qquuiitt(())and
the cclliicckk bbuuttttoonn(())functions, which we’ll put to use in a
moment
Finally, we get into using PHP-GTK We start off by
creating an instance of the GtkWindow class, and by
setting its title and size This is the first window that our
application will show, and it will be 300 pixels wide by
150 pixels high, with a title bar of “Hello world”
To add some excitement to this we will also fill the
window with a small text label and an “OK” button In
GTK, if you want more than one widget in your window
you first have to “pack” the widgets into a container
(either vertical or horizontal), and this container is then
added to the window (or, optionally, to another
con-tainer) “Widgets” are the graphical elements with
which you build your application’s interface—things
like labels, buttons, and lists
The ccoonnnneecctt(()) method calls in Listing 1 serve to
con-nect a user event with a callback function The first
ccoonn nneecctt(()) call tells GTK it should call our cclliicckk bbuuttttoonn(())
function when the button is “clicked” This function
uses the label widget’s sseett tteexxtt(())method to change the
label’s text to show we clicked the button
The second ccoonnnneecctt(()) call tells GTK to call our qquuiitt(())
function when the user clicks the window’s Close
but-ton (the X in the upper right corner) The qquuiitt(())
func-tion ends the applicafunc-tion by stopping the “main loop”,
which is started on the last line of Listing 1
The GTK main loop is really what sets apart PHP-GTK
applications from web-based PHP applications It is
what makes the application run and respond to events,
and to compare it with a web application is a little
tricky For instance, a PHP web application draws the
user interface once (outputs HTML) A PHP-GTK
appli-cation, however, redraws its user-interface constantly in
response to events While the whole user interface is not
redrawn on every iteration of the main loop, any
pend-ing changes (such as our label text change) are
updat-ed on each iteration
Now that we know what Listing 1 does, let’s see it in
action PHP-GTK applications, like their command-line
cousins, are started by running the script with your PHP
interpreter If you’re running Windows, for instance,you can start it as shown in Figure 1 You may noticethat the DOS window from which you start the PHP-GTK script hangs and waits for the script to terminate
This means that every PHP-GTK tion you run comes with its very ownblack DOS window, which is not so nice
applica-if you plan to run these applications on aregular basis
In the Windows PHP-GTK distributionpackage there is a special php_win exe-cutable that behaves a bit differently fromthe normal executable The php_win exe-cutable starts the script, detaching it fromits DOS window This makes it look moreneat and professional
More theory
So, the workflow for developing a
PHP-1 <?php 2
3 /*
4 Load the gtk library, a tiny check to see if we should use
5 the dll or the so file The so file is normally used on *nix
17 /* Change the text in the $label text box */
18 $GLOBALS [ ‘label’ ]-> set_text ( ‘Thanks for clicking ok.’ );
19 }
20
21 /* Create the window with “Hello world” as title and a
fixed size */
22 $window = &new GtkWindow ;
23 $window -> set_title ( ‘Hello world’ );
24 $window -> set_default_size ( 300 , 150 );
25
26 /* Create a small label with the following text*/
27 $label = &new GtkLabel ( ‘test’ );
35 /* Use a verticle box container */
36 $box = &new GtkVBox ();
37
38 /* Pack both of the to objects in there */
39 $box -> pack_start ( $label );
40 $box -> pack_start ( $button );
41
42 /* Fit the box into the window */
43 $window -> add ( $box );
44
45 /* Connect the quit() function to the delete_event signal */
46 $window -> connect ( ‘delete_event’ , ‘quit’ );
Trang 28GTK application is to instantiate, initialize, and pack the
interface widgets, set up callbacks to handle any
rele-vant events, and start the main loop
Almost every GTK object has events (often referred to
as signals in GTK) that can be caught and handled
These could be anything from from a window losing
focus, to characters being entered into a textbox
These events form the foundation of GTK applications
If no events happen or get caught, your application will
just sit there doing effectively nothing By catching
events, you can do all sorts of weird and wonderful
things
It is important to remember that when developing
PHP-GTK applications everything depends on the main
loop As an example, let’s say you have a normal loop
in one of your GTK callback functions that performs a
large number of iterations If you change something in
the user interface (like a label) in the middle of this
loop, the interface won’t actually be updated until your
callback function returns In fact, your loop would
actu-ally lock up the entire application, not allowing any
events to be processed until the main loop regained
control Fortunately, there is a way around this which
we’ll see when we get to Listing 4
Let’s now take a look at some of the problems with
PHP-GTK applications
Drawbacks of PHP-GTK
One thing that has followed PHP throughout time is
limitations in its memory management Since most PHP
scripts are expected to have a lifetime of a matter of
seconds, allocated memory isn’t released until the script
ends Unfortunately, this also applies to PHP-GTK
appli-cations, and results in the process hogging more and
more memory over time This is an important
consider-ation to take into account when planning, developing,
and deploying a PHP-GTK application, especially for
applications that will run for long periods of time, like a
whole business day or several weeks This problem has
been discussed many times on the PHP-GTK mailing list
and while there are some solutions that have been
reported to work, none of them seem to be a quick fix
Another issue is the packaging and distribution of
your finished application Unfortunately, there is no
easy way to make a self-contained package, or
applica-tion binary One soluapplica-tion I tried was adding PHP code
to the actual PHP interpreter executable itself This
approach worked nicely, but had size limitations that
made it almost hopeless to use for anything more than
educational purposes
One of the biggest problems I’ve encountered when
creating PHP-GTK applications is the excessive number
of objects—one for each layout element In large
appli-cations, this can get really hard to keep track of, so I
usually organize them all into a global array (such as
$$WWIIDDGGEETTSS) This way I know where everything is, and I
can var_dump() it to easily see what’s in there Anexample of this will be shown in Listing 4
As you may have guessed by looking at Listing 1, itwould require a lot of code to create the user interfacefor larger applications This can be reduced, of course,
if you start making general functions for all kinds of dows and common tasks, but in the end the drawing ofthe interface is just not very nice to do with code Itwould be much better if you could just drag and dropinterface elements like in Visual Basic or Delphi, andthen just add the logic to the interface Guess what?This is exactly what you can do if you use Glade
win-Introducing GladeGlade is the desktop application equivalent of web pagetemplates, and is a good way to separate our code fromthe user interface Glade uses XML to describe the lay-out of an application, so it would be possible for you togive the design work to someone else and then just pro-gram the “behind-the-scenes” logic to activate the userinterface
Another benefit of using Glade is that you don’t have
to write all that code necessary to create the user face Instead, you can use a user-interface builder (seeFigure 2) to just drag and drop what you want, set allthe relevant widget properties (such as name and size),and then export it all to a Glade file
inter-I used wGlade (http://wingtk.sourceforge.net) forthe examples in this article Other Glade interfacebuilders exist, but I find wGlade very easy to use
To demonstrate how it works, I changed Listing 1 toget the user interface from a Glade file Have a look atListing 2, and see how much cleaner it is Listing 3shows the Glade file used in Listing 2
Let’s take a look at Listing 2, and explain what we did.The first difference is that we now load the Glade file,creating the $$ggllaaddee aapppp object which can be used toreach all the widgets in the layout Once we have vari-ables pointing to these widgets, the rest of the code isthe same as Listing 1
So far we have limited ourselves to the GtkWindow,GtkButton and GtkLabel widgets, but there are plentymore; for example, GtkEntry, GtkCombo, GtkMenu,and GtkCalendar You can find a complete list of widg-ets at developer.gnome.org/doc/API/gtk/gtkobjects.html
Building a port scannerNow that we’ve got the basics down, and can useGlade to ease the interface development, let’s do some-thing practical, and create a small port scanner Alongwith performing a meaningful task, this example willalso serve to introduce some new widgets The codefor this example can be found in Listing 4 (not listeddue to length), with the Glade file in Listing 5 (not list-
ed due to length) Both listings can be found in thismonth’s code package
Trang 29Again, wGlade was used to build the interface (Figure
3) The wGlade application is kind of buggy in places,
and you may end up having to enter some property
val-ues manually in the Glade file—I had to do this with the
window’s default width and height
As you can see in Listing 4, I have organized all of the
relevant widgets from the Glade file into the $$WWIIDDGGEETT
array This way it’s easier to manage them Next, we see
the ppoorrtt ssccaann(())function that does the actual connection
attempt, and the ppoorrtt sseerrvviiccee(()) function that returns a
service likely to be running on a specific port number
The ddiiaalloogg(())and cclloossee ddiiaalloogg(())functions are a good
example of how you can combine a Glade application
with “regular” PHP-GTK constructions ddiiaalloogg(())accepts
a string as an argument, and shows this string in a
dia-log window with an OK-button We create the diadia-log
window from scratch using the GtkDialog widget, and
then add a GtkLabel and GtkButton to it
The functions uuppddaattee ssttaattuussbbaarr(())and
uuppddaattee pprrooggrreessss bbaarr(()) are used to update the status bar and progress
bar, respectively
The ssccaann(()) function is really the main part of the
application It gets the IP address, port, and timeout
information from the options tab and the scan tab, and
then performs the actual scanning ssccaann(()) also
man-ages to find time to update the user interface while
scanning
The progress bar and the status bar are two of thenew widgets we used in this example, and they areextra important—especially when understanding themain loop The actual scanning consists of a while loopwhich runs from the start port number up to the endport number Inside of this loop we do the following:
• update the progress bar
• update the status bar
• check if the port is open; if it is, add a row tothe clist widget
• start the GTK main loop manually to finish
up pending tasks
• continue to the next port
In the fourth item we are starting the PHP main loop
to finish up pending tasks What is that? Well, in item 1and 2, we updated the progress bar and the status bar,but that wasn’t actually reflected in the interface.Instead, the update was queued; the actual update isnot done until the main loop gets a chance to do it.That’s what the fourth item is for—we’re giving it achance to update the interface
At the end of the ssccaann(())function we update the
17 /* Change the text in the $label text box */
18 $GLOBALS [ ‘label’ ]-> set_text ( ‘Thanks for clicking ok.’ );
19 }
20
21 /* Create the glade_app object and load the glade file */
22 $glade_app = &new GladeXML ( ‘listing4.glade’ );
23
24 /* Get all interesting objects in the user interface */
25 $window = $glade_app -> get_widget ( ‘window’ );
26 $label = $glade_app -> get_widget ( ‘label’ );
27 $button = $glade_app -> get_widget ( ‘okbutton’ );
28
29 /* Connect the click_button() function to the clicked signal */
30 $button -> connect ( ‘clicked’ , ‘click_button’ );
31
32 /* Connect the quit() function to the delete_event signal */
33 $window -> connect ( ‘delete_event’ , ‘quit’ );
Trang 30tus bar once more to tell the user that the scanning is
finished This time, though, we don’t need to start the
main loop manually, as the function is finished, and will
be returning control to the main loop, anyway
The rest of the script is almost the same as in the first
example, and is pretty standard for most PHP-GTK
applications
The application is now ready to be used (see it
run-ning in Figure 4) While it may not contain all features
that you would expect from a port scanner, it is a good
example of a PHP-GTK application to look at and learn
from This port scanner is limited to IPV4 IP address,
and the way it determines if ports are open or not is
probably not the most efficient
Real-world applications
So, all this sounds wonderful, doesn’t it? But do peopleactually use PHP-GTK? There are actually quite a num-ber of applications developed in PHP-GTK, and many ofthem are released with full source code, which offers apotential goldmine for learning
There is a nice list of applications at
http://gtk.php.net/apps I would like to mention a few
of these applications, and briefly introduce them toyou
The first one is a integrated development ment for web/GTK projects It’s called PHPMole, and is worth checking out at
environ-http://www.akbkhome.com/Projects/Phpmole-IDE.Another application is SAC.php, which is a contentmanagement system with a PHP-GTK administrationsystem
The last one is actually a game called DeepDungeons Deep Dungeons is a role-playing gamedeveloped with PHP-GTK, and can be found at
http://deepdungeons.sourceforge.net
Summing upAfter a whole article about PHP-GTK, you will hopefully
be eager to start writing your own applications It’sactually quite simple once you wrap your mind aroundthe concept of PHP as a desktop application language.And Glade makes it even easier (although it’s not with-out its problems)
PHP-GTK has great potential, but there are still somekey issues holding it back, and those are probably a realpain for the developers of the GTK extension If we canget the packaging and distribution figured out, as well
as finding a solution to the garbage collection andmemory usage problems, I think more companies willstart exploring it
I hope I inspired you to embark on new adventuresthrough the PHP jungle Please drop me a note if you
do something really cool
Click HERE To Discuss This Article http://forums.phparch.com/59
When Eric's not out skiing or hiking, he's working as a freelance
develop-er on various projects His current focus is finishing his education in open-air alpine environments.
Trang 31Our continuing coverage of php|cruise takes us all
the way “across the pond” to the Old
Continent—to Great Britain, to be precise—
where this month’s featured speaker resides
Wez Furlong is a well-known PHP author, and is a
developer of PHP, responsible for such features as the
streams API and the new SQLite extension I have had
the opportunity to chat with Wez on a few occasions,
and when we started kicking around names of
poten-tial speakers for php|c, he was one of the first we
tapped—and I’m glad we did, because he has come
through with some excellent talks
php|a: Wez, let’s start with a quick introduction for
our readers What is your role in the development of
PHP?
I wrote and implemented the
Streams API found in PHP 4.3 (which
required a fairly broad understanding
of the whole of the PHP internals), and
have worked on a number of other
extensions and interfaces to PHP, such
as ActivePHP SAPI, OpenSSL, COM
(which I rewrote for PHP 5), mailparse,
sqlite, sysvmsg, and a SAPI interface to
load PHP 5 into the Irssi IRC client
(known as php-irssi)
In addition to code, I also help to
keep the php.net systems ticking from time to time,
and started up a project to replace the slow and CPU
intensive docbook build system we use for the PHP
manuals with a very fastand flexible alternativeusing PHP and SQLite—
I call this livedocs rightnow, but sinceMacromedia has some-thing with that name, itwill probably need to
be renamed
php|a: What
attract-ed you to PHP? When did you join the proj- ect?
It was initially work related One of my first tasks inthe commercial world of programming was to rewrite
and maintain a UK site where peoplecould advertise their property (houses)for sale I rewrote this from some cus-tom Unix C code into an ASP site Atthe time, I’d never heard of PHP before(even ASP was new to me) A year or solater, that same employer had a poten-tial customer that wanted a web basede-learning system, but it had to rununder Unix So we looked around andfound out about this thing called PHP3—it sounded like ASP, it was free andeven better, it used C-style syntax and could even sendemail without installing a third-party component Whatmore could you ask for? :)
Speaker on the High Seas
An Interview with Wez Furlong
by Marco Tabini
“I really like the idea of making PHP work in places it has never been before!”
Trang 32So we adopted PHP for the project At that time, PHP
4 was in late beta, so we started out with PHP 3, and
later migrated to PHP 4 After a while, we felt the need
for SSL sockets to be returned from the fsockopen()
function (to use for some credit card authorization
stuff), so I cooked up a simple patch to do it and
sub-mitted it to the php-dev list This was sometime in
September of 2000
As time went by, I refined my patch a little, but was
frustrated by the way that the PHP code handled
sock-ets vs plain files—the code was nasty, and it just wasn’t
easy to make the SSL stuff working without making it
any uglier After some discussion, I suggested making
the socket stuff more modular, and I think it was Andrei
Zmievski that suggested making the whole of the PHP
file access more modular It took some months of
jug-gling in my spare time to get this fully implemented,
but finally, the Streams API was born
php|a: Are there any other PHP-related projects
you’re working on? For example, I know you were
working on a version of PHP that could be
embed-ded in other applications, and you recently ported
the Lemon parser to PHP.
Yes, I really like the idea of making PHP work in places
it has never been before!
My first foray in this field was the ActivePHP SAPI,
which allows PHP to be used from any ActiveScript
enabled application, including but not limited to—
Internet Explorer (client-side), ASP (server-side), and
Windows Scripting Host
People often jump when they hear that they can use
PHP on the client side—well, don’t get your hopes up
too high—PHP is just far too powerful to safely deploy
on the client side of a browser Just pretend that you
didn’t hear that it was possible, and save yourself a lot
of security issues!
The ActiveScript SAPI is still quite beta (the PHP 5
ver-sion, which I need to rewrite, will be much better) In
terms of real world use, the WeaverSlave IDE has
sup-port for scripting/macros using this
In a similar way, I’ve embedded PHP into the irssi IRC
client using Edin Kadribasic’s Embed SAPI, and more
recently, I’ve begun work on a cross-platform email
application that uses an embedded version of PHP 5 toreduce the burden of coding the presentation layerwhich would otherwise have been implemented usingC++
I also initiated a project that I call livedocs to replacethe slow, heavy and inflexibile openjade way of trans-forming DocBook XML into HTML
php|a: You were also one of the principal architects
of the new SQLite extension Can you tell us what prompted you to develop it and in which situations SQLite will be most useful?
Well, I had a deadline to finish an article for a based magazine When it comes to writing, I find that Ican either sit there and type it out, or not I was in the
PHP-“not” phase and needed something to occupy mymind I’d heard of this thing called SQLite before, andheard that someone else had written an extension for
it I looked at the code for this thing and realized that
it was totally broken and was surprised that it couldeven work as well as it did
As a challenge, I allowed myself 2 hours to ment the basic features of the SQLite library fromscratch 2 hours later (on the nose!) I had a workingextension—and it turned out to be pretty good Sincethen, others have helped develop the extension, andMarcus Boerger has even come up with a whole OOAPI for it in PHP 5
imple-In terms of use, SQLite is particularly well suited to uations where you need to retrieve data based on someselection criteria—e.g.: looking up data cross-refer-enced by names and dates SQLite is very fast, since itdoesn’t have the overhead of a “real” RDBMS, so youget performance and simplicity (flat file with SQL inter-face!) in a single package
sit-SQLite is NOT well suited for situations where youhave a very high degree of concurrent users makingupdates to the database SQLite locks the whole filewhen making an update, and if you have a couple ofhundred users attempting to update at the same time,you get a massive blocking problem There are tricksyou can use to reduce this, but to be honest, if you are
in that situation, you can or should be able to afford areal database
Most people using MySQL with PHP aren’t reallyusing it except as a glorified filesystem; in terms of theoverhead there (administration, maintenance and run-time access speed) it makes more sense to use SQLiteinstead Of course, SQLite doesn’t have all the features
of MySQL, so it’s not really a drop-in replacement for it
in existing projects, but an alternative choice you canmake when you are writing your application
php|a: What do you think are the best new features
of PHP5?
“PHP would really benefit
from something like the
.Net framework,”
Trang 33The new object model has to be the number one
fea-ture Aside from the benefits to user code, it finally
allows extensions to wrap OO based libraries properly
(and more easily) For example, I completely rewrote
the COM extension for PHP 5, and it kicks ass It works
the way COM is supposed to work—COM exceptions
are mapped to PHP exceptions, and variant types are
supported much more thoroughly This just wasn’t
pos-sible before
One of the other features that not many people know
about, is that the ZE2 now has streaming support in its
scanners/lexers This allows much greater flexibility for
people writing stream implementations to be able to
create a stream from any source
(not just a file or socket based
resource) and feed that into the
scanner
In layman’s terms, it makes it
easy to implement custom
encrypted/encoded storage for
their code, without requiring it
to be stored in a temporary file
on disk (which could potentially
reveal the source code) This isn’t
really a major point, but it’s just
another one of my contributions that means a lot to
those that will end up making use of it
Sterling Hughes (and others) have been looking at
the performance for PHP 5, and I think it is actually
faster than PHP 4 in a lot of cases So, our overall
per-formance should be better too
php|a: Do you think these features will cause PHP to
become more popular in new environments (like
the enterprise, for example)?
They will definitely make PHP much more attractive
to these (almost mythical!) Enterprise people However,
in my opinion, what will really make them sit up and
take PHP even more seriously is a rock solid class library
PHP would really benefit from something like the
.Net framework, but I just can’t see something like that
being produced by a community spread across the
globe with no dictator to decide what should be done
PEAR isn’t theanswer to this—its goals are different—a
community where anyone can (and does) contribute
code, no matter how small, or how useful
Don’t get me wrong—PEAR is a very useful
resource—there are some brilliant packages in there,
but it makes the enterprise people nervous Is the code
any good? Is the code safe to use—either as-is, or can
we modify it to fix problems? GPL and even the LGPL
can present big legal problems to these guys
Luckily, the new COM extension also provides
inte-grated support for Net, so this will be less of an issue
under Windows
However, sweeping aside my negative opinions for a
moment, PHP 5 is a much more attractive propositionfor the enterprise than PHP 4, although I expect it will
be PHP 5.1 before they really start to pick up on it
php|a: Tell us about what you plan to talk about at php|c.
I will be presenting 3 sessions:
Socket Programming in PHP 5 will focus on using
the new socket transport features I added to theStreams API in PHP 5 In addition to introducingthese things, I will show how to write portable,
working socket code, bothclient-side and server-side I’veseen too many PHP classeswhere people play with socketsettings when they don’t need
to They also abuse things likenon-blocking mode—youalmost never need to use that
So, if you aspire to be a socketguru, you should find this ses-sion very useful
E-mail Manipulation and Transmission in PHP —
correctly building up or working with standardscompliant e-mail can be a tricky task In the past,I’ve worked on some commercial grade web-mailsoftware and had to learn these standards In addi-tion, the software needed to be capable of sendingmail using a Far-Eastern character set In this ses-sion I will be sharing some of my hard-earnedknowledge for your benefit
My final session is about Extending PHP If you are
ready to ascend to the ranks of an internals hacker,
or are looking at exposing your business logic (thatyou have already written in C/C++) to the webusing a simpler interface, this session will be anideal starting point There isn’t enough time toreveal all the internals magic of PHP, but there will
be enough that you can take a C library and make
a functional PHP extension for it
“PHP is just far too powerful to safely deploy on the client side of a browser.”
php|a
Trang 34For those of you who have been keeping track of the
impending release of PHP 5, one of the most talked
about new features will be the introduction of the
SQLite into the standard PHP release For those of you
who haven’t been following the development of PHP 5,
I think some introductions are in order SQLite is, as it’s
name implies, a relational database package which
allows you to store data within tables in databases (just
like MySQL) However, SQLite is unique from any other
database packages in a number of ways which I’ll go
over now
Differences between SQLite and other
databases packages
The single biggest difference—and greatest benefit—
when comparing SQLite to other database packages is
its architecture Most other common RDBMS packages,
such as MySQL, work using a client/server system
where the SQL client (in our discussion, this would be
PHP) would store and retrieve data to and from a
data-base server SQLite, on the other hand, stores and
retrieves data in databases locally without the need for
an additional server Since PHP 5 now ships with both
the database package and the interface to use it,
devel-opers can leverage their SQL knowledge in developing
PHP applications, but not have to worry whether the
end user will have another RDBMS package (such as
MySQL) or not To make this look even more appealing,
SQLite will be bundled (both the library and the
exten-sion) with PHP 5, making the need to develop custom
filesystem storage mechanisms for your scripts obsolete
The end result is that scripts are both easier to developand maintain
SQLite is typelessNow that you understand why SQLite fills a niche whichwas until now void in PHP, let’s take a look at the differ-ences between SQLite and other RDBMS packages in abit more detail For starters, SQLite is a typeless data-base engine This means that, like PHP, SQLite does notdistinguish an integer from a string or any other type ofdata In fact, when defining tables in SQLite just aboutanything can be used to describe the data type of a col-umn This is quite different in comparison to, forinstance, MySQL, which has a predefined notion of dif-ferent types of data and treats each type differentlywithin the database
Although SQLite does not require the explicit tion of typing information for each column within atable, it does have a very generalized concept of typingthat is based on the data type provided, and that isessential for the database to properly function InSQLite, data is classified into one of two categories:
declara-“textual” or “numeric” These classifications aredesigned to assist the database engine in determining
Code Directory: sqliteREQUIREMENTS