Tài liệu Introduction to Version Contron with CVS doc - Pdf 90

VOLUME II - ISSUE 11
php
|
Cruise
March 1
st
- March 5
th
2004
See inside for details
Get Ready For
www.phparch.com
NOVEMBER 2003
Plus:
Tips & Tricks, Book Reviews, Product Reviews and much
Introduction to Version Introduction to Version
Control withControl with
Discover the power of collaborationDiscover the power of collaboration
CVSCVS
Implementing Web ServerImplementing Web Server
Load ManagementLoad Management
Preventing resource overloads
Working with PEAR::XML_SerializerWorking with PEAR::XML_Serializer
XML has never been so easy
Introduction to PHP-GTKIntroduction to PHP-GTK
Getting started with desktop applications in PHP
An Introduction to SQLiteAn Introduction to SQLite
SQL for the masses
Object Overloading in PHPObject Overloading in PHP

Visit us at www

In partnership with Zend
Technologies
Zend Studio 3.0 is the
official PHP IDE of
php|cruise
Features
php
|
Cruise
Traditional PHP
Conference*
Conference Pass
$ 899.99
**
$ 1,150.00
Hotel
Included
($ 400.00)
Meals
Included***
($ 200.00)
Totals:
$ 899.99
$1,750.00
You Save $ 850
* Based on average of two major PHP conferences
** Based on interior stateroom, double occupancy
*** Alcohol and carbonated beverages not included
ENJOY LEARNING PHP IN A FUN AND EXCITING
ENVIRONMENT—AND SAVE A BUNDLE!

Introduction to Version Control with
CVS
by Dejan Bosanac
25
Introduction to PHP-GTK
by Eric Persson
30
Speaker on the High Seas
An Interview with Wez Furlong
33
An Introduction to SQLite
by John Coggeshall
44
Working with PEAR::XML_Serializer
by Stephan Schmidt
52
Implementing Web Server Load
Management
by Rodrigo Becke Cabral
3
November 2003

PHP Architect

www.phparch.com
TABLE OF CONTENTS
II NN DD EE XX
II NN DD EE XX
php|architect
Features

Address: _________________________________________
City: _____________________________________________
State/Province: ____________________________________
ZIP/Postal Code: ___________________________________
Country: ___________________________________________
Payment type:
VISA Mastercard American Express
Credit Card Number:________________________________
Expiration Date: _____________________________________
E-mail address: ______________________________________
Phone Number: ____________________________________
Visit: for
more information or to subscribe online.
Signature: Date:
To subscribe via snail mail - please detach/copy this form, fill it
out and mail to the address above or fax to +1-416-630-5057
php|architect
The Magazine For PHP Professionals
November 2003

PHP Architect

www.phparch.com
EE DD II TT OO RR II AA LL RR AA NN TT SS
EE DD II TT OO RR II AA LL RR AA NN TT SS
php|architect
Volume II - Issue 11
November, 2003
Publisher
Marco Tabini

ciated material.
Contact Information:
General mailbox:
Editorial:
Subscriptions:
Sales & advertising:
Technical support:
Copyright © 2002-2003 Marco Tabini & Associates, Inc.
— All Rights Reserved
I
like to consider myself a fairly adept PHP
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 doc-
umented on
www.php.net
. Countless others
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

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...
November 2003

PHP Architect

www.phparch.com
6
EDITORIAL
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.

PHP 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 in
PHP 5, all extensions are now focused
around the excellent libxml2 library
(
/>).
• SQLite has been bundled with PHP. For
more information on SQLite, please visit
their website.
• A new SimpleXML extension for easily
accessing and manipulating XML as PHP
objects. It can also interface with the DOM
extension and vice-versa.
• Streams have been greatly improved,
including the ability to access low-level
socket operations on streams.
There have been many changes since Beta 1,
some of them documented in the NEWS file and
most language changes are documented in
ZEND_CHANGES “
November 2003

PHP Architect

www.phparch.com
7
• the System class for quick handling common

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
to act like a basement 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
be very welcome.”
Get more information or download from
Sourceforge.net
at:
/>:object::kitchen R4
Objectkitchen announces release number 4.
What is it?
Objectkitchen is a Java application used through a
client/server-style connection from your application. It
was written with the following goals in mind.
It should be very easy to use. An average program-
mer should be able to start storing and retrieving object
data within 15 minutes of installation.
NNEEWW SSTTUUFFFF
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

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 earlier line and the closing backtick has not yet been seen.
Get more information or download from
MySQL.com
.
November 2003

PHP Architect

www.phparch.com
8
It 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

• 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:
/>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
NNEEWW SSTTUUFFFF
PHP-GTK 1.0.0
PHP-GTK announces the release of version 1.0.0.
What is it?
PHP-GTK is an extension for PHP programming lan-
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.
The release announces: “PHP-GTK Version 1.0.0

English, even if its authors are not native English
speakers. I believe Direction|PHP will create oppor-
tunities for both French authors and companies to
step up to the plate and shine “, adds Damien
Seguy.
Get more information about Direction|PHP, visit
their homepage.
What 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

by Alessandro Sfondrini
PHP: 4.3.3+
OS: N/A
Applications: MySQL 4.0.12, Apache 1.3.27
Code:
/>Code Directory: object-overloading
REQUIREMENTS
class Greet {
hello() {
System.out.println(“Hello World”);
}
hello(string name) {
System.out.println(“Hello “ + name);
}
hello(string name, string from) {
System.out.println(“Hello “ + name);
System.out.println(“Greetings from “ + from);
}
}
LISTING 1: Basic OO example in JAVA
doesn’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

____ggeett(())
method works.
First, we set the
$$ggrreeeett
property. 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 to
FALSE, to zero, to a blank string, or to whatever makes
sense.
Finally, we return TRUE from
____ggeett(())
. This is because
all of the “magic” methods should only return TRUE or
FALSE. This tells the parser whether the access was suc-
cessful—returning FALSE will make the parser display a
notice (“Notice: Undefined property”).
Before we can test this class, we must overload it

The
____sseett(())
method stores the value of the undefined
property that the user tried to set into an associative
array (
$$eelleemm
), and then returns TRUE. Like for
____ggeett(())
,
returning FALSE will cause a notice.
Next, we put an if-else control in method
____ggeett(())
. If
the undefined property is stored in the
$$eelleemm
array, we’ll
set
$$PPrrooppVVaalluuee
to that value, otherwise set the value to
our error message. Finally, we return TRUE. Note that
we could return FALSE instead of setting the property to
our error message—in that case we could only get the
properties we’ve set (trying to get undefined properties
we’ve never set would cause a notice).
Let’s test it out. After having overloaded the class, we
set an undefined property (
$$ffoooo
) to 3.14. Next, we get
$$ffoooo
and print it. Finally, we try to get and print anoth-

// Sets the value
10 return TRUE;
// Returns TRUE = doesn’t display errors
11 }
12 }
13
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
It 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

FALSE (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 the
class, we try to call three methods: method
ggrreeeett(())
, the
PHP 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, but
got a warning. This is because we decided not to
accept
lloogg(())
as a valid method to our class. Also notice
that in
____ccaallll(())
we had to pass the parameter as an
array element (
$$FFuunnccAArrgg[[00]]
). That’s a problem, since it
means we can only call one-argument functions! To fix
this we can use the
ccaallll__uusseerr__ffuunncc__aarrrraayy(())
PHP function.

20 }
21
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
27
28 ?>
LISTING 3
1 <?php
2
3 function greet($name) // An user-defined function
4 {
5 return “Hi $name! <br/>”;
6 }
7
8 class TryCall
9 {
10 var $accept;
11 function TryCall() { } // Constructor is empty
12
13 function __call($FuncName, $FuncArg, &$RetValue)
14 {
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[0]);
// Executes the function

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,

$$aacccceepptt
. They are both asso-
ciative arrays—the key is the method name and the
value is the MySQL function name. Note that the prefix
“mysql_”, which each function should have, is omitted
for simplicity and will be added when we execute the
call.
Now comes the most important part of our class. It’s
all contained in an if-elseif-else block.
• If the function called as a method is valid
and requires the connection link, we will add
$$lliinnkk
to the parameters array, call the func-
tion, and return TRUE
• If the function is valid, but doesn’t require a
connection link, we will simply call it and
return TRUE
• If the function is not valid, we will return
FALSE (the script will return a warning)
After having called a MySQL function, the script will
check if it has been successful. If it hasn’t, a MySQL
error message obtained by
mysql_error()
will be dis-
played.
Now our class is complete—we only have to overload
and test it. We create a new object, passing the connec-
tion parameters to the constructor, and then select the
database. Next, we execute a SELECT query on the
November 2003

table 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 “clas-
sic” meaning of overloading. We also explained that in
PHP, we can’t redeclare a method. You might have
guessed that
____ccaallll(())
, though, can help us to do some-
thing similar. It won’t be as elegant as it could be in Java
but... it will work!
Imagine we have a method on which we want to
allow overloading. What we have to do is to prepare
different methods using the original method’s name
concatenated with the number of arguments passed to
November 2003

PHP Architect

26 );
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()
34 );
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
50
51 } // End __call()
52
53 } // End class
54
55

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 the
methods. 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 to
overload the constructor, which would allow us to build
different 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 the
line:
overload(“ClassName”);

PHP Architect

www.phparch.com
14
FFEEAATTUURREE
Object Overloading in PHP
1 <?php
2
3 class JavaOverLoad
4 {
5 function JavaOverLoad() { } // The constructor is empty
6
7 function __call($FuncName, $FuncArg, &$RetValue)
8 {
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);
11 return TRUE;
12 }
13 /* Some methods... */
14 function greet0()
15 {
16 echo “Hello World! <br/>”;
17 }
18
19 function greet1($name)
20 {
21 echo “Hello $name! <br/>”;
22 }

has already written some on-line PHP tutorials and published scripts on
most important Italian web portals. You can contact him at

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

your development team is changing the code directly
on the server, you could suppose that this article has no
value for you—but don’t jump to conclusions. CVS is
November 2003

PHP Architect

www.phparch.com
15
FEA
FEA
TURE
TURE
Introduction to Version Control with CVS
PHP: 4.x
OS: Any
Applications: N/A
Code: N/A
Code Directory: N/A
REQUIREMENTS
by Dejan Bosanac
much 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

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 (

),
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
direc-
tory.
We’re now ready to use CVS in the local environment.
In later sections some other interesting configuration
issues for remote servers will be introduced.
When using CVS as a client, we need to tell the client
program where the code repository is. We can do this

that everything is fine, and start working on the source
that is under CVS control. First, we should move the
current project to a temporary folder.
$ mv /home/web/e-commerce /home/web/e-commerce.orig
And do the checkout.
$ cd ..
$ cvs checkout e-commerce
U e-commerce/index.php
U e-commerce/login.php
U e-commerce/login_form.php
The checkout command fetches the latest version of
all the files that are in the repository and puts them in
the “e-commerce” folder. To be sure that this code is
the same as the original code, we could do something
like this:
$ 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. Maybe
now is a good time to remove the original source fold-
er, just to be sure that we don’t accidentally edit it
November 2003

PHP Architect

www.phparch.com
16
FFEEAATTUURREE
Introduction to Version Control with CVS
instead of the files that are under CVS. Before you do
this, you may want to consider backing it up some-

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.php
was 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 between
working 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 means
that the local copy of the file has been changed and
that those changes have not yet been committed to the

> echo “E-commerce 1.0 - under construction”;
This line will give us the exact changes between the
working 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 line
two.
The next thing we want to do is to commit our work
to the repository so other developers can use it. We can
accomplish 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 as
with the update command. This is useful in situations
when you have finished one piece of functionality and
started another. You need to submit only the changes
November 2003

PHP Architect

www.phparch.com
17
FFEEAATTUURREE

$ cvs -qn update
A logout.php
$ cvs commit –m “Added to the project” logout.php
Checking in logout.php;
/home/office/cvsroot/test/logout.php,v <— logout.php
initial revision: 1.1
done
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
the operation.
$ cvs commit –m “Removed from the project” logout.php
Removing logout.php;
/usr/local/cvs/e-commerce/logout.php,v <— logout.php
new revision: delete; previous revision: 1.1
done
If you are not sure about the statuses that the update

e-commerce_conflict
directory like this:
<?
echo “E-commerce 1.0 - under construction”.“-debug”;
?>
and run the update command, you’ll see the following
message:
$ cvs -q update
RCS file: /usr/local/cvs/e-commerce/index.php,v
retrieving revision 1.1
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.php
now looks like this
<?
<<<<<<< index.php
echo “E-commerce 1.0 - under construction”.“-debug”;
=======
echo “Debug:“.“E-commerce 1.0 - under construction”;
>>>>>>> 1.3
?>
The conflict has been clearly marked, and you can see
that two different lines have been found at the same
place in the different revisions. You can resolve this con-
flict in one of two ways. You could choose to delete the
local copy and replace it with the version in the reposi-

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
Repository
file 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-commerce
or
/usr/local/cvs/e-commerce
.
The
Entries
file 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

D/name/filler1/filler2/filler3/filler4
• name
is the name of the subdirectory
• filler
fields are left for future enhancement.
An example entry for the system subfolder would be:
D/system////
Now that you know how the working directory CVS
directories are organized, we will briefly go through the
repository organization, which will give us an idea of
how the other side works. The repository is just a direc-
tory on your server (or a remote server, as we will see
later). Project files are stored in the repository with
names 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 also
contain all of the comments that were entered in the
import and commit process (remember the “-
m”switch). This way a complete log history of each file
can 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.php

each line.
Aliases have the following syntax:
November 2003

PHP Architect

www.phparch.com
19
FFEEAATTUURREE
Introduction to Version Control with CVS
alias_name –a what_to_alias
For example, let’s go back to our
e-commerce
directory
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

[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 to
your specific organization’s needs.
The first thing you should think about is the location
of the CVS server. All of our previous examples assumed
that the CVS repository is on the same server as the
working directory. This is acceptable in some cases, but
not always. If we go back to the example of the open-
source project with developers spread all over the
world, this configuration would not be very useful.
What we need is a CVS server that is publicly available
via the Internet for developers to use. Fortunately, using
remote repositories is as easy as using local ones. All you
have 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 the

cvs_username
, you would end up using
the 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 pass-
words from the
/etc/passwd
file. In this case you should
consider protecting the
$CVSROOT/CVSROOT
directory with
the same privileges as the
/etc
directory to prevent
malicious users form compromising your CVS server.
If CVS can’t find a username or the passwd file it will
try system user look-up (system password file, LDAP,
November 2003

PHP Architect

www.phparch.com
20
FFEEAATTUURREE
Introduction to Version Control with CVS
etc) in order to try to authenticate the user. This feature

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
readers
and
writers
files in the
$CVS-
ROOT/CVSROOT
directory. You can create and modify these
files (as well as the
passwd
file) 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

Branches
CVS 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 of
your project. Let’s say that we have released version 1.0
of our e-commerce suite, and continued on to work on
the 1.1 release. After a while, a client calls and reports a
bug in the code, but our repository has changed since
that release and we don’t have an accurate version of
the source to work on.
Every branch has its own number. Branch numbers
consist of an odd number of period-separated integers.
The revision number of the file being branched
becomes the branch number followed by a period and
an integer. In Figure 1 we can see examples of the file
revision 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 .
T index.php
T login.php
T login_form.php
Now, when you need a working copy of some earlier
product release, you can access it by using the “-r”
switch with the name of the branch on checkout and
update commands. First, you need to checkout the
branch and create a working directory for it.
$ cd /home/web

) with the PHP plug-in
(

) 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 (
/>) 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 (

) is a set of GUI’s
available for the Windows, Macintosh, or
Unix/Linux environments. It’s a powerful appli-
cation that uses the native look-and-feel of
your operating system. It contains a file brows-
er, a module browser, command line support,
and many other advanced features that can
help experienced users to automate their tasks.
See Figure 3.
Chora (

This article has only covered the tip of the iceberg
with CVS and associated tools. There’s much more to
learn, and you’ll find a ton of information on the web,
so check it out!
November 2003

PHP Architect

www.phparch.com
23
FFEEAATTUURREE
Introduction to Version Control with CVS
Figure 2
About the Author ?>
Click HERE To Discuss This Article
/>Dejan Bosanac works as a fulltime software developer for DNS Europe Ltd
() on the Billing software system for ISP's. In
his spare time he also serves as a Lead Engineer at Noumenaut Software
() 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 />call 1-866-4FAVOR1 now for information.
- Strong support team


Nhờ tải bản gốc

Tài liệu, ebook tham khảo khác

Music ♫

Copyright: Tài liệu đại học © DMCA.com Protection Status