This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
|
30 PHP Library for Permissions Management no permission on individual documents. Even if a user has permission to an object category, he does not automatically receive the same permission on objects within this category. The publisher user is a bit different from the folderadmin. He has the role of publisher on all folders, but this role gives only READ and ADD_ELEMENT permissions. So, the publisher can add elements and access all folders, but cannot modify the folder itself (lmoving the folder elsewhere, for example). The viewer user has READ permission on all. This permission is granted through group membership. Viewer is part of the GROUP_VIEWERS group, which is given READ permission on both object categories (folders and doc- Figure 2 FEA T URE uments). Figure 2 shows the list of users. superadmin is selected, and the relative permissions, directly assigned to this user are shown. Figure 3 shows a more complex use of permissions, as used in a real application. The Flash GUI shows the object category information. For each of them, you can see which permissions are assigned to users, through roles, groups or directly. In Figure 3 CORE_SCRIPT is the selected object category. No users or groups have relations with CORE_SCRIPT. Only the Agenda Main Administrator Role has been assigned to (at least) one user, relative to CORE_SCRIPT. We have seen how to assign permission in many different ways, directly to users, using roles, and through groups. This scheme grants flexibility and can be adapted to many applications with good initial planning. The developer must determine which permissions will be needed within his application, differenciating between object categories, groups, and roles. Again, it’s important to define the correct list of permissions. After this scheme is created it’s straightforward to add authorize() calls in your code to let your code reflect the planned permission scheme. Authorize: Our Application User Interface The current user needs to be identified to the library when the application begins execution. After this, requests for the permissions of the current user can be made via a single method, called authorize(). Every kind of authentication can be used to identify the user, the user table is very general, and can be shared with your preferred authentication library. The authorize method can be called in three different modes: Authorize(PERMISSION_DEFINE) : This specifies only the requested permission. Authorize returns true only when the current user has this permission, but not when it is only relative to an object or on an object category. The user must own the permission outright (for each object type). This is typically used to create “super” users. A u t ho r i z e( P E RM I S S IO N _ D EF I N E ,O B J E CT _ T Y PE ) : Determine if the current user has been granted the PERMISSION_DEFINE permission on a specific category of objects (called OBJECT_TYPE). For example, a user could Figure 3 NO TE: The Flash client is provided as compiled file only, but some implementation details, such as the application model for validating input fields using regular expressions, can be found on Bernhard’s homepage at http://www.bgxcomponents.com. July 2005 ● PHP Architect ● www.phparch.com 31 PHP Library for Permissions Management have WRITE permission on all documents (given that we have a category of objects that includes all types of documents)—this will grant WRITE permission on all documents, but not on other categories of objects, like folders, assuming we defined folders as a different category of objects. Authorize(PERMISSION_DEFINE,OBJECT_TYPE,OBJECT_I D): You can determine if a given user has access to a single, specific object. To do this, you must specify both the object category (OBJECT_TYPE) and the unique id of the object (OBJECT_ID). The OBJECT_ID is unique only in the set of objects included in the OBJECT_TYPE category of objects. Common GUI for a common Library So far, we’ve only talked about building a good library that provides for the needs of many different applications, but what about administering the data? A common GUI, pre-built and easy to deploy, would be very helpful. Again, the objective is to provide a ready-made package you can plug into your own application. We decided to provide this in form of a single, compiled Flash file that communicates with the server via XML. Reasons to use Flash For simple forms (e.g. an ordering form, or even shopping cart solutions) stateless HTML based GUIs that are (re-)constructed and downloaded with every data exchange are fine. For more complex applications like our permissions editor, however, a solution that can maintain state on the client and could also take care of some of the more complex GUI components needed, like editable tree structures, would be a distinct advantage. Flash provides rich, platform independent client capabilities within a lightweight vector-based, easily downloadable and well distributed runtime environment. While Flash has always been very well known for its graphic and animation capabilities, for our permissions application it was more Flash’s extensive scripting Dynamic Web Pages www.dynamicwebpages.de sex could not be better | dynamic web pages - german php.node FEA T URE capabilities that were key. In particular, Flash allows: • data to be organized in such a way that only small chunks need to be loaded as the user requests them • the use of complex data objects such as user-permission trees on the client • client-side state retention • the creation of complex form based GUIs • binding data to a large set of readily available GUI components like lists, combos, and trees that can also be customized • the tracking of changes, client side, and submission of only data that has changed (e.g. when saving) Flash has evolved into a true rich internet application architecture, meaning parts of the business logic can reside on the client while exchanging data only with the server. Client-Server Communication The API used to communicate between the Flash client and the server application is generic so that the Flash client could be swapped for any other client that can send and retrieve data via HTTP and understands XML. How is this done? On the client side, we have created a PHP page to which predefined QueryString and Form parameters can be sent to request certain types of data (e.g. users filtered by a search parameter) in XML format. The page can also receive data to be saved to the database. For our Flash file, we have provided an external settings file which you can use to specify the exact URL for the different calls. By default we assume that the Flash file resides in the same directory as the xml_creator.php page that processes the calls, but you could change the URL to whatever suits you. The XML_API.doc file describes the calls that can be made to the server. You can try them out by simply entering the URLs into the address field of your browser. This document also describes the structure of the XML that is returned for each call. The client is expected to populate an appropriate GUI with the submitted data, and handle changes. To submit changes to the server, an XML string has to be sent as a form parameter to a PHP page that will handle the save request. Within this XML document are sections for changed, new and deleted data. When notifying of new or changed data, the whole object (e.g. a user or group definition) is sent, but in the case of a deletion, we send only the ID of the object in question. This way you get a very lightweight communication model for data exchange, requiring only the minimum data to be sent at a time. news . scripts . tutorials . downloads . books . installation hints July 2005 ● PHP Architect ● www.phparch.com 32 PHP Library for Permissions Management FEA T URE Client Customizations With the settings.xml file from which Flash reads the URL definitions for the commands, you can also control the appearance of the client (to some extent). Primarily, you can cjamge all of the labels that appear in the GUI, allowing you to change the language from English to whatever you need. There are also some CSS-like style definitions for the graphical appearance that you could change, and finally regular expression validations for various field types. For example, you might want to change the input requirement for passwords from “^[a-zA-Z0-9]+$” to something else. Conclusion The presented library should suit many applications, allowing an immediate and easy implementation via the permissions API. Authentication types are not predefined and can be created as needed. A flexible and easily deployable Flash GUI is provided (in the code archive) to administer the permissions library database, using a generic XML “gateway” that could be used to create other front ends if needed. July 2005 ● PHP Architect ● www.phparch.com EDITOR’S NOTE: The code provided by the authors, for this article, is very extensive, and the submission contains binary files (the Flash client, for example). As such, we have decided to refrain from printing the entire code, and have instead included it only in the code archive (zip file) that accompanies this article. About the Author ?> Simone is about to start a PhD at Trinity College in Dublin on Model-Driven Architectures next Obtober. Bernhard is a multimedia developer and general user interface specialist based in Dublin. To Discuss this article: http://forums.phparch.com/231 33 NEXCESS.NET Internet Solutions 304 1/2 S. State St. Ann Arbor, MI 48104-2445 http://nexcess.net PHP / MySQL SPECIALISTS! Simple, Affordable, Reliable PHP / MySQL Web Hosting Solutions P O P U L A R S H A R E D H O S T I N G PAC K A G E S MINI-ME $ 6 95 SMALL BIZ $ 2195/mo /mo 500 MB Storage 15 GB Transfer 50 E-Mail Accounts 25 Subdomains 25 MySQL Databases PHP5 / MySQL 4.1.X SITEWORX control panel 2000 MB Storage 50 GB Transfer 200 E-Mail Accounts 75 Subdomains 75 MySQL Databases PHP5 / MySQL 4.1.X SITEWORX control panel 16 95 /mo 900 MB Storage 30 GB Transfer Unlimited MySQL Databases Host 30 Domains PHP5 / MYSQL 4.1.X NODEWORX Reseller Access NEXRESELL 2 $ We'll install any PHP extension you need! Just ask :) PHP4 & MySQL 3.x/4.0.x options also available 59 95 /mo 7500 MB Storage 100 GB Transfer Unlimited MySQL Databases Host Unlimited Domains PHP5 / MySQL 4.1.X NODEWORX Reseller Access : CONTROL php 5 4.1.x P O P U L A R R E S E L L E R H O S T I N G PAC KA G E S NEXRESELL 1 $ NEW! PHP 5 & MYSQL 4.1.X php 4 3.x/4.0.x 128 BIT SSL CERTIFICATES AS LOW AS $39.95 / YEAR DOMAIN NAME REGISTRATION FROM $10.00 / YEAR PA N E L All of our servers run our in-house developed PHP/MySQL server control panel: INTERWORX-CP INTERWORX-CP features include: - Rigorous spam / virus filtering - Detailed website usage stats (including realtime metrics) - Superb file management; WYSIWYG HTML editor INTERWORX-CP is also available for your dedicated server. Just visit http://interworx.info for more information and to place your order. GENEROUS AFFILIATE PROGRAM UP TO 100% PAYBACK PER REFERRAL 30 DAY MONEY BACK GUARANTEE FREE DOMAIN NAME WHY NEXCESS.NET? WE ARE PHP/MYSQL DEVELOPERS LIKE YOU AND UNDERSTAND YOUR SUPPORT NEEDS! WITH ANY ANNUAL SIGNUP ORDER TODAY AND GET 10% OFF ANY WEB HOSTING PACKAGE VISIT HTTP://NEXCESS.NET/PHPARCH FOR DETAILS Dedicated & Managed Dedicated server solutions also available Serving the web since Y2K FEA T URE Change Your Life with Version Control: An Introduction to Subversion F E A T U R E by Clay Loveless Imagine a world in which you work harmoniously with other developers, never fearing that your code changes will overwrite theirs—or worse, that their changes will overwrite yours. A world where all of your modifications are backed up, and where you can always perform an “undo” operation when your code tweaks take a turn for the worse. Sound like a dream come true? Welcome to the Subversion-managed life. I f you’re not already using a version control system to manage your work, you may be one of many developers with a nagging “Man, I need to take time to figure that out” thought in the back of your mind. The one that pops to the forefront every time you see a line like the following, in an open-source project you’re hacking on: $Id: index.php 3128 2005-05-01 22:02:26Z clay $ Or, you may be a developer who’s been working for a while without using a version control system, and you think “Hey, I work alone and I get by just fine without that stuff. What’s the big deal?” Change to workflow management is something that simply gives a lot of developers the shivers. No one wants to time testing out new ways to work—if you’re already overworked, adding new steps to your workflow is just going to make everything take longer, right? In this article we’ll explore why taking the time to integrate version control into your work is worth the effort. In doing so, I’ll introduce you to Subversion, a version control tool that is rapidly gaining favor with the open source development community. What is Version Control? Version control is the process of keeping track of changes that are made by one or more parties, to a collection of files. July 2005 ● PHP Architect ● www.phparch.com The art of software development is often made up of a series of exploratory events. You may know the requirements of the project or task you’re working on— you know what you ultimately want to achieve—but getting from the beginning of a project to the end may require some (or lots of) trial-and-error style exploration. Version control tools are designed to help you keep track of the small, incremental changes you make along the way, similar to the idea of leaving a trail of breadcrumbs behind you as you venture deep into the forest of your project. By making use of version control, REQUIREMENTS PHP 4.3 OS Any supported by Subversion Other Software Subversion 1.0 or later, PEAR::VersionControl_SVN Code Directory subversion RESOURCES URL htt p:// sub ver sio n.t igr is. org / i URL htt p:// svn boo k.r ed- bea n.c om/ 35 FEA T URE Version Control: An Introduction to Subversion you can always find your way back if you realize that you’ve gotten lost. Beyond keeping a basic record of changes, version control systems also provide mechanisms to merge changes made by more than one person to the same file or files. It is this ability to manage concurrent changes by members of development teams that the magic of version control really starts to kick in. Why You Need Version Control You may be like me—I resisted the idea of version control when I first learned about it. I started off working in want an easy way to help you out by contributing patches to your code. How do you manage all the helpful input and integrate it into your work? All of these issues can be addressed effectively by integrating a version control regimen into your workflow. Introducing Subversion, Heir Apparent to CVS The Concurrent Versions System (CVS) is the de-facto standard version control tool. CVS, which has been around in various incarnations since the late 1980s, “The art of software development is often made up of a series of exploratory events.” web development as a self-taught independent contractor, and since I worked alone, I figured I did not need to use a tool that was designed to help teams of programmers work together. I had a little system of creating a copy of a file before I veered off in a radical new direction, and I knew that I could always go back to that saved version of the file if didn’t like where the new direction took me. There are a few problems with this approach. First, what if you have made some changes in your “new direction” version that you want to keep, but you want to discard some changes? It’s hard to remember exactly everything you changed so that you can carry only the changes you want back to your saved backup. Next, what if you forget to make enough backup copies? Often, the exploration of a new approach to solving the programming problem will involve a number of small branches that may seem too small to be worth saving entire backup copies of the files you’re working on. The sense of security you had when you made your original backup copy is eroded when you realize you didn’t have just one branch from the main development, but you’ve really made several branches. How about the bugs you introduced during all that fiddling around with the code? Before I got hooked on version control, I spent many long hours backtracking through multiple-undo operations, hoping that my editor wouldn’t crash while I was stepping backwards through changes to find where I’d goofed up. On the positive side, what if what you’re working on becomes The Next Big Thing? When other developers line up to help, they will want to be able to see how you got to the current state of the project, and they will July 2005 ● PHP Architect ● www.phparch.com evolved from a series of UNIX shell scripts written to solve the problem of merging the work of multiple developers working together on a project into a central copy of the work that combined the input from each developer into a unified whole. The container that holds this central copy, as well as the history of changes to it, is known as a repository. Like many solutions that evolve organically as the problem definition clarifies itself, CVS was patched and extended in order to meet new requirements as they came up. Features such as secure network connections to a repository server and versioning of binary files (such as images), in CVS, behave almost as though they were afterthoughts, and require the user of the system to remember special incantations in order to use those features properly. After more than a decade of CVS use as the primary solution to the version control problem, the requirements of a complete version control workflow were well-known. In early 2000, a group of developers began work on a new version control system called Subversion, whose primary goal was re-imagining CVS’ solution to the version control concept from the ground up, without any of CVS’ quirks and design flaws. Subversion can handle several aspects of versioning a project that CVS cannot; for example: • Subversion tracks changes to directories and files; CVS can only track changes to files. • Subversion allows flexible access and authentication policies over HTTP, HTTPS, and SSH. • Subversion can track metadata properties 36 Version Control: An Introduction to Subversion related to the files and directories in a repository, in addition to changes to the files and directories themselves. • Subversion tracks revisions as they relate to an entire project, not only as they relate to individual files within a project. While there are many version control tools available today, whose implementations improve upon the concepts pioneered by CVS, Subversion is the only free, open source solution designed specifically to duplicate CVS’ use in a development workflow. Conceptual Overview: What are we trying to do? There are a variety of ways to take advantage of Subversion: command-line tools, GUI applications, integrated solutions that provide access to Subversion as part of a larger application, and web-based Subversion interfaces. We’ll cover all of those methods, but before we dive into the details of basic svn usage, let’s describe what we’re really trying to accomplish with Subversion, and version control in general. First, we need a place to store the code for the project we’ll be tracking with version control—that place is called the repository. A Subversion repository can be created locally on your development machine, on your development server, or it can be provided for you as part of Subversion repository hosting service. Some version control novices are confused by the concept of the repository, since they are used to only having one copy of the code for their projects stored in a local directory where they make edits, and a web server that the files are uploaded to when edits are complete. If you find the repository idea confusing, you’re not alone; I found the concept of an invisible, allknowing repository the most difficult to get a grasp on when I first began working with version control tools. Think of the repository as a refrigerator—you store a pizza in the fridge, take it out and “work on it” by eating a slice or two, and then put the modified pizza back in the fridge. A repository is similar in that you keep your code in the repository, and you checkout a copy of the code to work on it. (A repository isn’t exactly the same as a refrigerator—the repository keeps copies of all previous versions of the project, enabling you to go back to any specific revision if you need to. I wish my fridge let me do that with pizza!) If you are not working on a project that already lives in a Subversion repository, you will first need to import the project that you want to track revisions on. If you’re starting work on a new project, it’s a good idea to import an initial directory structure for the project to establish a starting point. The checked-out copy of the code is called a working copy. Just like when you’re working on a non-version July 2005 ● PHP Architect ● www.phparch.com FEA T URE controlled project, you often need to do any or all of the following tasks while making edits: make changes to one or more lines of code in files already in the project, add new files to the project, copy files from one directory to another, move files around, and possibly even delete files or directories entirely. When you’re finished making changes to your working copy, you tell the repository about the changes you’ve made by performing a commit operation. Occasionally you may find that you need to stop working on the project for awhile to handle something else before you’ve been able to commit your changes. When you get back to working on the project (hours, or even days or weeks later), you’ll probably want to take a moment to figure out the status of the changes you made during the last session to you can determine exactly where you left off. If you will be working on a project with others, or even just making custom modifications to an open source project that is housed in a Subversion repository, you will want to make sure that your working copy is current before each editing session. To do that, you will need to perform an update operation, which will pull down anything that has changed from the repository since your last editing session. When updating your working copy on a project that is being worked on by multiple developers, you may find that someone else has made changes to files that you’ve been editing. In that event, you’ll need to merge the changes you’ve made with the changes the other developers working on the project have made. Sometimes the changes you’ve each made will be to different sections of the same file, in which case merging is an easy task. There are times, however, when you find that you’ve each been working on the same section. In those instances, you’ve got a conflict that you will need to resolve. If the series of events I’ve described above sounds somewhat similar to your work flow process, now, integrating Subversion into your routine will be a piece of cake. Basic Subversion Setup & Workflow If you’ve followed me this far, we only have a few small steps to take to get you up and running using Subversion to manage your projects. As I mentioned there are several Subversion-aware tools available to make it easy to manage your work, in a repository. All tools are based on the fundamental svn command-line tool, so for now we will focus on converting the conceptual narrative above into usable commands with svn . First, let’s assume that we’ve got Subversion example.com installed on our server at https://svn.example.com/ . The main Subversion website offers detailed installation instructions, as well as 37 Any more, and we’d have to take the exam for you! We’re proud to announce the publication of The Zend PHP Certification Practice Test Book, a new manual designed specifically to help candidates who are preparing for the Zend Certification Exam. Available in both PDF and Print Written and edited by four members of the Zend Education Board, the same body that prepared the exam itself, and officially sanctioned by Zend Technologies, this book contains 200 questions that cover every topic in the exam. Each question comes with a detailed answer that not only provides the best choice, but also explains the relevant theory and the reason why a question is structured in a particular way. The Zend PHP Certification Practice Test Book is available now directly from php|architect, from most online retailers (such as Amazon.com and BarnesandNoble.com) and at bookstores throughout the world. Get your copy today at http://www.phparch.com/cert/mock_testing.php Version Control: An Introduction to Subversion links to several pre-packaged installers for a wide variety of platforms. I will also assume (and suggest!) that you have the latest stable version installed, Subversion 1.1. You also need to consider the access methods you want to allow to your repository. Repositories, and directories within repositories, may be controlled with FEA T URE and the path where we’d like the repository to live on the server. Two file storage types are available for a repository: BerkeleyDB and the filesystem type. As of the upcoming Subversion 1.2, fsfs is the default and recommended type of repository storage, so if you’re starting a new repository it’s a good idea to get started with what will be the standard, going forward. Finally, “The repository keeps copies of all previous versions of the project, enabling you to go back to any specific revision if you need to.” an access control list (ACL). You can use an ACL to set whether projects are read-only, publicly readable but require authentication for writing, or totally private, where read and write operations require valid authentication. Authentication can be secured via SSL or SSH, or “non-secured,” meaning that authentication credentials can be required, but will be transmitted in plaintext over the network. Server-based repositories can be set up using any or all of the following methods: • svn:// : A non-secured protocol which does not require anything other than the standard Subversion installation. Network access is facilitated via the svnserve daemon. • svn+ssh://: Secured protocol which uses system accounts for authentication, and upon successful login, spawns an svnserve process as the authenticated user. • http:// : A non-secured access method that utilizes HTTP for communication. Requires Apache2 with Subversion modules installed. • https:// : Secured access method using HTTP and SSL. Requires Apache2 with Subversion and mod_ssl modules installed, plus an SSL certificate. (May be a self-signed certificate or a certificate issued by any SSL vendor. Try out a GoDaddy.com SSL cert if you feel your project might meet the requirements for their free open source SSL certificate.) If you choose either the http:// or https:// method, make sure you set your repository’s permissions so that the directory is owned by the Apache2 user. Begin by creating a repository, if you do not already have a repository available: $ svnadmin create —fs-type fsfs /var/lib/svn The svnadmin create command does not generate any output upon success. The options we’ve passed to the command specify a filesystem-only type of file storage, July 2005 ● PHP Architect ● www.phparch.com please modify the repository path of /var/lib/svn as needed to fit your environment. Now, let’s create a test project with an empty file structure. $ mkdir tmpdir && cd tmpdir $ mkdir -p testproj/trunk testproj/branches testproj/tags $ svn import . https://svn.example.com —user exampleuser \ —password examplepass \ —message “Project starter layout” $ cd .. && rm –R tmpdir The empty directory structure that you’ve given to your test project follows the standard layout suggested by the Subversion documentation. This layout is generally adhered to by most Subversion users. The purpose of the directories in an empty project structure break down like this: • trunk : The main thread of current development in the project. • branches: Experimental development branches that may eventually be merged into the project trunk. • tags : Directory for saving, or “tagging”, copies of the project at a particular point in time, such as version releases, site launch milestones, etc. So now you’ve got a shell for your project in the repository. The next thing to do is to check out the project into your working area, where you can add files, test your changes, and generally, just hack away. $ svn checkout https://svn.example.com/testproj \ —user exampleuser —password examplepass \ ~/sandbox/testproj A testproj/branches A testproj/tags A testproj/trunk — Checked out revision 1. What just happened? You checked out your test project from the repository, and saved a working copy of the project in your “sandbox” development area. The letter 39 FEA T URE Version Control: An Introduction to Subversion A in front of each directory indicates that the directory was added to your working copy. If you are actually using an https:// -based repository, the above output would also include a prompt for acceptance of the remote server’s certificate credentials. After seeing the first svn command with username and password arguments, you may be wondering if you’ll have to use those arguments with every command. The good news is: No! While the above example shows the username and password as part of the command, by default Subversion only requires this on the first command. Subversion will attempt to cache the credentials used to access the repository, and will use them transparently for future operations. (Note: the svn+ssh:// method does not attempt to cache credentials.) If you are using a shared machine, you may be concerned about the security risks of credentials caching. Cached credentials are stored in ~/.svn/auth (or %APPDATA%/Subversion/auth if you’re using Windows) in a permission-protected state which allows only the user who issued the command that cached the credentials to read them. In other words, other users on the machine will not be able to access your credentials— just make sure you log out of your session before leaving the machine unattended! If you are still concerned about the security of Subversion’s default credentials-caching behavior, you can disable authentication caching for single commands by adding the —no-auth-cache option, or by disabling caching permanently in the Subversion run-time config file that lives alongside the auth/ directory mentioned above. See the Subversion manual’s section on “Client Credentials Caching” for more details. With a working copy of our test project checked out in our “sandbox,” it’s time to get started—working just like you normally would. Using the testproj/trunk directory, create files as needed, add directories as needed, and conduct your development as usual. The notion of version control comes back into play when you’re ready to commit a version of what you’re working on. In our test project, let’s assume that we’ve copied in a couple of standard files that you may find in many projects: README , COPYING and INSTALL. Put those files in your trunk directory, either by creating new files or copying them in from another project. Now, let’s see what we’ve got: $ svn status ? README ? COPYING ? INSTALL What that tells you is that Subversion sees that there are some files in a version-controlled directory (your working copy) that it doesn’t know about. To tell Subversion that you want to track revisions on these files, you need July 2005 ● PHP Architect ● www.phparch.com to formally add them to your test project. $ svn add README A README $ svn add COPYING A COPYING $ svn add INSTALL A INSTALL Now Subversion knows about these three files, and will display an A instead of a question mark if you perform another svn status operation. Now that your working copy knows that these files should be tracked, you can commit them to the repository. $ svn commit –m “Adding basic info & doc files to project” Sending README Sending COPYING Sending INSTALL Transmitting file data ... Committed revision 2. Note that since we were committing all of the files that we added, we did not need to specify what files we were committing in the svn commit command. The message Adding basic info & doc files to project will be recorded in the repository log along with your username and a timestamp. Please make a habit of writing something informative in your commit messages— you never know if the project you’re tinkering with will become the next phpMyAdmin. If that happens, other developers will appreciate your efforts in documenting your changes. A sentence or two will do! Don’t be lazy and commit a series of changes with a message stating fixed some bugs—that kind of message won’t help you or anyone else if and when it’s time to backtrack through the log. How do you know when to commit a version, or revision? That’s a good question, and one whose answer may vary on a case-by-case basis. For example, you may be learning version control techniques to become a participating member of a multi-developer project. If that is the case, find out from the project leaders what their repository commit policy is, if any. A good rule of thumb is to commit a revision when you get to a point where you feel you would not like to have to re-do what you’ve done, much like the decision you make on when to hit Save in your editor. Another good rule is to try to commit changes that actually work. If you feel like you must (or should) commit a revision that you know is broken in some way, make a point to note what is broken clearly in your commit message. If you find that you need to commit some of the files that have changed in your current working copy, but you’re not ready to commit them all—or if it does not make sense to commit all current changes under one commit message—then you need the —targets command option. This option allows you to reference a file that lists out all of the files in the working copy that should be included in the current commit operation, 40 FEA T URE Version Control: An Introduction to Subversion and therefore tagged with that commit message. A handy way to make use of this feature is to keep an alias to a file called svn, which resides in the home directory, somewhere close at hand (I keep mine in the Mac OS X dock—adjust this suggestion to your operating system of choice). That way, you can quickly open the ~/svn file and add a list of files that you want to commit. Using this technique, every —targets commit can look like this: $ svn —targets=~/svn –m “Added new maintainer to package.” Create files and directories, add them to the project with svn add , and commit. Repeat. Make changes, commit with useful log messages, repeat. Keep up this routine, and it will pay dividends later. A few things that strict adherence to this allow you to do: Look back on the long, strange trip. It’s a fairly common practice to build ChangeLogs out of repository commit messages. Detailed commit messages, combined with svn log , can give you a nice overview of the progression of a project’s codebase. How’d we get here? Dig back into the past to find out what specific changes were made to a file to get to the current state. For example, svn diff -r10 index.php will compare the current revision (also known as HEAD ) of index.php with revision 10 of index.php. Abort, Abort! svn revert can let you back out of all changes you’ve made since the last revision was committed. Working and Playing Well with Others So far, the techniques we’ve covered outline the benefits and basic usage of Subversion for an individual. The main points to know when using Subversion as part of a development team are how to merge changes and resolve conflicts, and the importance of svn update. When working with a group, it is important to remember to run svn update in your working copy at the start of every editing session. (If you’re working on a particularly active project, it may make sense to run it several times during a single editing session.) svn update updates your working copy with the current revisions in the repository. Often, running svn update will be a smooth operation. The command will put out a list of changed files that it has updated in your working copy, new files that have been added, and possibly files or directories that have been deleted. Subversion will note these changes in your working copy by listing the related files, prefixed with U, A or D, respectively. However, on occasion svn update will pull changes from the repository that affect files that you have been editing in your working copy. In these instances, those files will be denoted with a G, for mer ged, or a C, for conflict. When you see a G , it means that Subversion July 2005 ● PHP Architect ● www.phparch.com noticed that you’d been making changes to the same file, but your changes did not overlap the changes made to the version in the repository, so Subversion automatically merged your changes in with the new revision. In the event of a conflict, that means you and another developer were working on the same section of code within a file. To bring the world back into harmonious balance, you will need to manually review the differences between your edits and those of your colleague. Subversion tries to make this process easier by creating a few extra files in your working copy. Let’s say that you’ve been making changes to the opening paragraph of your project’s README document, while another developer has been making changes to the same section. When you run your svn update command, something like the following will occur: $ svn update C README Updated to revision 3. $ ls -1 README README.mine README.r2 README.r3 The three additional files alongside README are called conflict markers. At this point, you have three choices: Manually compare README.mine with README.r3 , and if necessary, README.r2. README.r3, in this example, is the revision you just pulled from the repository. README.mine reflects your current changes, and README.r2 reflects how README looked before any editing started by either party. When you’re done manually examining the files, make edits to README, as appropriate. Copy one of the three conflict markers over README. Run svn revert README to discard your changes. After completing one of the above three choices, you should then run svn resolve to let Subversion know that you feel you’ve taken care of the conflict. At the risk of stating the obvious, it is important to realize that when Subversion successfully merges your working copy file with a changed file from the repository, what you’re left with may very well not be a functional file. In my (very) early days of understanding version control concepts, I wondered “How does the merge operation know if the changes from the repository should be merged with my changes?” The answer, of course, is that the tool doesn’t know—it’s just a tool, not an omniscient guardian angel. All that happens when Subversion automatically and “successfully” merges your working copy with the newly retrieved version of a file is that Subversion feels comfortable that the lines that another developer changed in the file are not in the immediate vicinity of the lines you are in the middle of changing. Hence, the guideline is to make sure you pay close 41 FEA T URE Version Control: An Introduction to Subversion attention what’s taken place whenever you perform an svn update operation, and double-check any merges or conflicts that the output of the command warns you about. Fun for the Whole Team When working as part of a diverse group that may include more than developers—or if you, yourself, prefer to stay away from command-line tools—there are a wide range of tools that have Subversion support builtin. A short and by no means complete list: • BBEdit: Version 8.1 of the venerable Mac editor offers built-in Subversion support. http://barebones.com/ • SVN for Macromedia Dreamweaver: Thirdparty plugin available in free and commercial versions. Currently Windows-only. http://grafxsoftware.com/ • psvn.el: Subversion interface for emacs, for the hard-core among us. http://xsteve.nit.at/prg/vc_svn/ • TortiseSVN: Standalone Windows GUI client for Subversion. http://tortisesvn.tigris.org/ • SCPlugin: Contextual Menu plugin for Mac OS X that adds Subversion support to the Mac OS X Finder. http://scplugin.tigris.org/ While it may be a challenge, it is worthwhile to try to integrate Subversion usage into an entire team, including copywriters, graphic designers, and yes, even marketing folks. A historical record of an entire project (not just the code portion) in one place is an extremely valuable resource if you can get buy-in on the concept from an entire team. Leveraging Subversion in Your Projects So, what’s all this got to do with PHP, seeing as this is a PHP magazine? From the beginning, Subversion has offered very tight integration with Perl, Python and Java. Subversion also comes with C libraries that can add Subversion functionality in applications such as those mentioned in the previous section. Until recently, Subversion integration with PHP has been lacking. There are two PHP packages available to make it easier to take advantage of a Subversion repository in your projects. PEAR::VersionControl_SVN: An OOP wrapper svn for the command. http://pear.php.net/package/VersionControl_SVN ext_svn: A PECL extension for Subversion. Uses the svn client libraries to add native Subversion functionality to PHP. Available from CVS only as of this writing. http://cvs.php.net/pecl/svn/ July 2005 ● PHP Architect ● www.phparch.com In addition to basic repository browsing functionality (See the cool FlexySvn for an example of that: http://newweb.akbkhome.com/svn.php), these packages can be used to add robust version control capability to web applications. For example, imagine a message board templating system that allows forum administrators to tweak templates with a browser interface, but saves those changes to a server-side working copy of the forum’s distributed template set. The web interface could also trigger periodic svn update commands to a publiclyreadable repository to merge distribution-level template changes with customized templates. A number of CMS applications offer some form of internal versioning, but none of those custom-built versioning systems allows external editing of those versioned documents. With the integration of Subversion capability, a CMS application could be extended to allow content editing from within its interface, or via Subversion, with changes accessed again through a server-side, PHP application-triggered repository checkout. (Note: svn export might be a better command to trigger in that type of scenario.) The VersionControl_SVN package is well documented with examples for each method it offers—please see the online documentation at the PEAR website for more ideas on how to integrate Subversion into your applications. Start Tracking Changes Today! I know that adding version control to your working process can be a chore that does not seem like it is worth the effort. However, I hope that I’ve shed some light on what benefits await you if you take the time to integrate Subversion into your work. Don’t waste time getting on the bandwagon—put down this magazine and jump online and Google for “Subversion hosting.” There are a number of services that offer relatively inexpensive repository hosting, and many of those offer free trial periods. Try out what you’ve learned, immediately, without getting bogged down in the details of setting up your own repository server. Good luck, and don’t forget to commit your work, often! About the Author ?> Clay Loveless has been developing web applications with PHP since 1997’s PHP/FI 2.0b6. A New York University-trained actor, Clay now works from California as an independent internet solutions consultant under the name Killersoft (http://www.killersoft.com). He is also actively involved in maintaining Pearified.com. Clay is a husband, father of a very cool one year old son, and a dedicated Boston Celtics fan. Reach Clay via clay @killers oft.co m. To Discuss this article: http://forums.phparch.com/232 42 FEA T URE Creating a Simple Image Gallery by Martin Psinas This is version 2.0 of an older, much more rustic image gallery that was previously published on codewalkers.com. I was amazed at how many people actually took interest in it, and even more amazed at how many bugs it had after getting carried away and sloppy with hasty improve- ments. I eventually became fed up with how un-manageable the code had become, and it finally got to the point that I abandoned the project, putting all development on hold until deciding (recently) to start again from scratch. M ther developing the scripts for use with larger galleries and/or high-traffic websites. At the time of writing, this article assumes you are using PHP version 5.0.4 along with GD version 2.0.28 (although it should run on a few older versions of PHP as well). ost of the philosophy behind the original project remains the same. I wanted an image gallery that doesn’t require a database, or an administration script; simplicity is the key. All storage will be handled by the file-system. Each directory will be a category (or sub-category, depending on the hierarchy), and the images will be sorted within these categories no different than you would organize them on your personal computer. Everything else, i.e. thumbnails, pagination, etc will be handled by the code. So when all is said and done, you should be able to transfer any directory of images to your web server, along with the scripts that we’re going to write and your gallery will be up and running without any required configuration. Editing the gallery is as simple as renaming folders, adding/deleting images, etc. I do not claim that this is the only approach, or even the best approach to construct an image gallery; it is a simple approach without too many bells and whistles. The code provided in this article is intended “as-is” for small to medium sized galleries; however, additional notes are provided near the end of the article for fur- July 2005 ● PHP Architect ● www.phparch.com Components The four scripts that we’re going to write are: • config.php – optional configuration options • imgsrc.php – the code for handling the images • gallery.php – the code for displaying the REQUIREMENTS PHP 5.0.4 OS Windows/Linux Other Software GD Library 2.0.28 URL http://www.boutell.com/gd/ Code Directory imagegallery 44 FEA T URE Creating a Simple Image Gallery image gallery • styles.css – a style sheet for the gallery The first step is come up with a layout of how we want our gallery to look. Our gallery will consist of five main components: The container is exactly what the name implies, a container for the other sections. The breadcrumb menu will always be displayed at the top of the gallery, whether we’re displaying categories, thumbnails, or a combination of both. This way we can always find our way back from whence we came. The category display is a section that will display categories vertically, if applicable Each category will be displayed as a thumbnail of the first image inside of that category, along with a count of how many images and sub-categories are inside. If the category doesn’t have any images (but does have sub-categories), we’ll just display a default thumbnail. The image navigation menu will allow us to navigate the many different pages of thumbnails. We will actually display this menu both above and below our thumbnails. And finally, the thumbnail display section will display our thumbnail images. Take a look at Figure 1 to get a better grasp on how the layout will be displayed. Pretty, isn’t it? The Set Up The first script, config.php, will consist of two parts: optional configuration options (Listing 1), and advanced configuration options (Listing 2). This code in Listing 1 should be pretty self-explanatory. We set up some nice default values, so altering these constants is completely up to you. Pay attention to the comments in my code as well, for further explanation. We start Listing 2 by assigning the server path to our main images folder. The default setting grabs the current working directory, and replaces back-slashes with forward-slashes to avoid conflicts between Windows and Linux servers. The path should always begin with a slash, but never end with one. It is recommended that you change this path to a folder outside of the public web-tree. The reason for this is because all calls to images will be going through imgsrc.php, which is the script that draws watermarks on our images. If someone visiting your gallery were to change the URL in their browser, they could potentially access your images, directly, to avoid the watermarks. However, if your images were stored in a non-public folder, this would not be possible. In the TYPE constant, we are defining what MIME types our script is allowed to work with. This will prevent our script from trying to mess around with files it shouldn’t, such as logs left behind from FTP programs or the image gallery scripts themselves. We have to seri- July 2005 ● PHP Architect ● www.phparch.com Listing 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 Listing 3 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Listing 6 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Listing 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 a:link, a:active, a:visited { color: #000080; font-family: verdana; font-size: 13px; font-weight: bold; text-decoration: none; } a:hover { color: #000080; text-decoration: underline; } img { border: 1px #CCC solid; } td { text-align: center; } td.category { text-align: left; border: 1px #DDD solid; } #main { margin: 0 auto; border: 1px #000 solid; background-color: #C0C0C0; } #navigate_categories { text-align: left; width: 100%; color: #000; border-bottom: 1px #000 solid; background-color: #FFF; font-family: verdana; font-size: 13px; } #display_categories { width: 100%; color: #000; background-color: #C0C0C0; font-family: verdana; font-size: 13px; } .navigate_images { text-align: center; width: 100%; color: #000; background-color: #FFF; font-family: verdana; font-size: 13px; } #display_thumbnails { border: 1px #CCC solid; width: 100%; background-color: #FFF; } Future Improvements The imagejpeg(), imagegif() and imagepng() functions all accept an optional 2nd parameter which would store permanent copies of both full sized and thumbnail images in the specified location. You could take advantage of this to use fewer resources as PHP would- 52 FEA T URE Creating a Simple Image Gallery n’t have to re-draw the images every time a page is requested. You would also need to modify imgsrc.php to first check if permanent copies exist, output them accordingly if they do, or create them if they don’t (and delete the originals). You’d obviously have to consider file permissions when adding this functionality. Adding the option to config.php for whether or not to store permanent copies would also be recommended in case you change your mind down the road. If you have an extremely large directory structure, you might consider caching the directory tree, perhaps in a session variable, so PHP isn’t re-gathering that information every time a new page is requested. Having PHP handle all image calls could allow for easy implementation of anti-leeching, preventing any websites that you don’t approve of from linking directly to your images. Nobody likes a bandwidth moocher. To support image descriptions, search functionality or the like, you would probably be better off converting the whole thing over to MySQL (which is obviously not the direction I am intending to go). In my vision, you would simply add an image description to the properties of an image on your local machine, and then have PHP read from that. I have nothing against databases, I’m just not a die hard “everything needs to have a database!” guy. Conclusion I would love to hear from anyone using my gallery, as it is a really good feeling to know it is out there being used. I also welcome any feedback or modifications regarding the code. The open source community has done nothing but great things for my life and I am happy to contribute. Please direct all questions or help/troubleshooting requests to either the codewalkers.com tutorials forum, or the php|architect forum. For all other inquires, you may contact me by e-mail at: [email protected]. About the Author ?> Martin Psinas, a.k.a. notepad, a.k.a. tapeworm is a volunteer administrator at codewalkers.com. He is also the author of the soon to be published “1337 h4x0r h4ndb00k” ISBN: 0672327279. Martin has been involved with computers since the summer of ’98, he is a freelance contract hacker by night, and during the day, he is a web developer for a local internet company based in central Illinois. To Discuss this article: http://forums.phparch.com/230 Award-winning IDE for dynamic languages, providing a powerful workspace for editing, debugging and testing your programs. Features advanced support for Perl, PHP, Python, Tcl and XSLT, on Linux, Solaris and Windows. Download your free evalutation at www.ActiveState.com/Komodo30 TE ST PA TT ER N T E S T P A T T E R N Not Just Nouns by Marcus Baker Your classes are your nouns and your methods are your verbs. The rule certainly is easy to apply, as you can just underline all of the nouns and verbs in your requirements document. There, object oriented design is easy! You are probably wondering what all of the fuss is about when such a simple rule is available. L et’s try out the noun/verb rule. Sometimes, when writing articles like this, my imagination needs a bit of a helping hand. I want to open up this project for tender and so write a formal requirements document. Here it is... “I, a person, will drink a beer when writing”. By our noun/verb rule this leads naturally to these classes... class Person { function drink($beer) { } } class Beer { } And already we have problems. Should Person have the drink() method or should the Beer class be rewritten as: class Beer { function drunkBy($person) { } } For that matter, the noun “Person” could have been “Drinker”, and “Beer” could have been “Drink”. Maybe these words are just the whim of the requirements writer? I bet two different sponsors on the same project will never choose the same set of terms. And the language affects our decisions, terribly. If a class is called Drinker then having a drink() method makes perfect sense. If a class is called Person , then should it really have a drink() method just for our rather unusual July 2005 ● PHP Architect ● www.phparch.com application? Person is going to end up a pretty big class if that is the rule, as people do quite a number of actions. To make things worse, where to place that method is vitally important to the architecture of the project. Take a look at Figures 1 and 2. In the first case, our Person class can see the Beer class as it is going to manipulate it. This is shown by the arrow. If Person is a central class in our application, and Beer is comparatively peripheral, this is bad news. If the Beer class changes for any reason, our Person will have to change, too. Having a central part of the system at the mercy of the fringe libraries is going to cause us endless rewriting with each minor change. The situation in Figure 2 is probably superior, and yet that wasn’t the one suggested by the wording on our initial statement. Is it just our lack of design experience that is getting us stuck and leading us into “analysis paralysis”? I don’t think so. I think we have already gone wrong. REQUIREMENTS PHP Any OS Any Other Software None Code Directory nouns 54 TE ST PA TT ER N Not Just Nouns The Business of Automation Let’s conduct a thought experiment. Imagine we are observing a production line through a camera. We are hoping analyze and model the processes of a car plant with the intention of improving it. The camera image is currently frozen and we are examining the scene. Straight away, we can see a car in different states of assembly. We can see engines and wheels, and various people associated with these parts. We can see all sorts of tools that help to make a car, such as wrenches and robots, and we can exactly catalogue every component of a car in excruciating detail. We can also work out what things have been done to the car, and can probably match them up with the tools. Can we then create a car assembly plant to order? We probably could, but we would have done it the hard way. Trying to understand a car plant like this is reverse engineering. You know there is an underlying plan, but you are trying to discover the cause from the effect. The resulting model is flat and fragile. There will be lots of part hierarchies, or composite patterns, if you rightly shy away from inheritance. I doubt every application has at its core the Composite pattern, but that is what we will get when looking at still images. What processes are important? How does the car plant react when something goes wrong, for example? How does the system adapt to build a truck? Or a plane? We haven’t really captured any of the important information. Luckily, our camera is really a video camera that is stuck on freeze frame. Let’s switch it to full motion and observe again. We immediately see a much richer picture. We can see the workers actually affecting changes on the vehicles as they move around the plant. We can see not just the assembly of the cars, but also which responsibilities belong to which workers and also how the workers themselves move around. Some of them probably do multiple jobs, for example. More obvious with full motion is something deeper still, the workflow of the plant. Rework loops and allocation of personnel are much clearer when we can see adaptation in context. We can see the main paths and also the exceptional circumstances. When something different happens, we can compare and see consequences. These are probably the real secrets of designing car plants, ones that are much more visible when we can see the motion. We lose almost all of the real insight when we view a problem statically. Software is not written to catalogue parts, it’s there to solve tomorrow’s problems. As programmers, we solve problems by creating a system that changes things automatically. We are also in the business of automation. The Power of Story Back to beer. We went wrong as soon as we identified July 2005 ● PHP Architect ● www.phparch.com theFigure nouns. 1 They are passengers, not the forces that Person Beer +drink() Figure 2 Person Beer +drunkBy() Figure 3 Data MoreData God EvenMoreData LessInterestingData CannotEvenRememberWhatThisWasFor drive the design. The design is driven by the verbs. Allocating these verbs is the tricky bit, as we have seen above, but it’s not so tricky with the cinema-like approach of the car plant observations. If we watch a headlight being assembled, we can observe a number of tasks, all being performed by the same person. The person that crimps the wires is also the person who ensures the insulation is correct. This makes sense. The headlight assembler has a skill set and a tool box associated with electrics, but we don’t need to know that beforehand. All we have to do is observe the single thread of the headlight assembly and look for how the actions are grouped. We look for roles. This following of a single thread with central characters is one of the oldest forms of communication there is. It’s called a story. This tradition reintroduces the vital ingredient of the flow of events back into our requirements gathering. If we want to understand the principle characters in a system, rather than be given a dry listing of objects, we want to be told a good story. Let’s illicit our requirements in that form… “Marcus is writing an article, but is feeling a touch of 55 TE ST PA TT ER N Not Just Nouns writers’ block. By raising his blood alcohol level, he can restart the flow of words. A beer is a possible source of blood alcohol when imbibed. There is a delay before it takes effect, so it is normally ingested before he starts writing the article.” and avoid dry lists of data. Sadly, we are shaped by our early experiences into being unwitting accomplices in our own demise: we often ask for data centric descriptions. Our first ever program was small. We could hold all of “ Software is not written to catalogue parts, it’s there to solve tomorrow’s problems.” We can do very much more than agonize over a UML diagram now. We can actually write some prototype code: $marcus = new Writer(); $marcus->imbibe(new Beer()); $article = $marcus->write(); We hardly have to think about where to place methods, because the tasks the objects have to perform are informed by the names of their roles... class Writer { ... function imbibe($drink) { $alc = $drink->getAlcohol(); $this->alcohol += $alc; } } Another problem with gathering requirements as mere descriptions is that you will get someone else’s interpretation of the appropriate abstractions. The concept of a drink dominated our first sentence, but it turns out that the drink is a mere container for something else: its role is to deliver alcohol. Whatever the exact words chosen with a story approach, this essential fact would not get missed. Programmers Love Data There are only two possible reasons why a project should have poor requirements. The first is the customer wrote them, and the second is the developer accepted them. Now, people writing formal documents are far more prone to a flat descriptive style. A formal document gets in the way of story telling, because the stories never escape the author’s head. The programmer reads them later and has to reverse engineer. When gathering requirements it is vital to use the richest possible communication medium. Face-to-face verbal communication is best. A phone conversation should be the bare minimum. Think interactive. The output of requirements gathering should be the transfer of knowledge from the expert to the developer. Any document is just a side effect. With direct contact, we have the opportunity to thrash out the real processes July 2005 ● PHP Architect ● www.phparch.com the data, if not the code, in our minds eye. This perfect vision was part of our early intoxication with programming. Unfortunately, it’s an expectation that doesn’t hold up well in the professional world. Partly the sheer scale of most problems is beyond what we can keep track of. Mainly though, it’s that data is often the least important part of a business. Like all of the fiddly little components in a car plant, data is a passenger. The core value will still be on data management rather than the data itself. For example, people are hired on the basis of their skills, not a photographic memory. The side effect of this is the data changes format all the time and is the least stable factor in modeling a business. If we naively model the data first and then try to write code to operate on it, as with our early programs, we will probably end up with something like Figure 3. If you were worried about the core depending on less stable modules in Figure 1, Figure 3 must have you panic stricken. Even minor changes to the business will ripple through the data, in turn causing major rewrites to the central class every time. You’d have a class that is already complex, and thus, extremely difficult to change. This way of writing software is called “data centric design,” and usually starts with the transposition of nouns into database tables. It can be quick to write, but is not robust. Listen for Roles If you are making use of objects, then you probably want their flexibility. A role based decomposition, rather than the structural decomposition of the data approach, distributes the information to those objects that need it most. Our headlamp assembler in our imaginary car plant has all the knowledge of headlamps, but no one else does. A different type of headlamp for a different model car will have negligible impact on the plant as a whole, even if the fitter needs retraining. Even abstraction won’t damage our encapsulation. We could use the same person to fit the ignition system. After all, they have the same electrical skills and both roles share the same tools. We can call this new 56 TE ST PA TT ER N Not Just Nouns role an electrician. This is an effective abstraction, as an electrician can be substituted for a headlamp assembler without change to any other part of the system. If your design is based around the physical headlamp, dropping in a different headlamp could have far reaching consequences… say, on the bodywork. A role is a noun too, of course, but it’s a very specific type of noun, usually ending in “er.” They hardly ever appear in documents, so you cannot underline them even if you wanted to. You have to tease them out. You have to talk. Use Cases or Less None of this is new, and established object oriented methodologies are often built around stories. Extreme Programming ( http://extremeprogramming.org) actually calls them “user stories,” for example, although it leaves it up to the programmer to make use of these. The Rational Unified Process (RUP, see http://www30 6. ib m. co m/s of tw ar e/ awd to ol s/ ru p/i nd ex .h tm l ) builds requirements analysis around “use cases”, which are just a formal format for a customer story. These fundamental artifacts include an explicit role-based decomposition, calling the roles “actors” in this case. For smaller in-house projects, where the stakeholders July 2005 ● PHP Architect ● www.phparch.com sit near the developers, this much documentation is too much. The developers can absorb the expert knowledge as day to day events unfold. If they are not directly within earshot, then social meetings exchanging war stories can fill the gap. If you manage such a project, then you might want to organize semiformal gatherings in the company’s interest. Make sure that the experts are comfortable, and you seed such sessions with open ended questions, such as “what happens next?” and “how can that happen?”. Of course, you will have to get colleagues to loosen up a bit. Perhaps a beer would help. About the Author ?> Marcus Baker works at Wordtracker (www.wordtracker.com ) as Head of Technical, where his responsibilities include the development of applications for mining Internet search engine data. His previous work includes telephony and robotics. Marcus is the lead developer of the SimpleTest project, which is available on Sourceforge. He's also a big fan of eXtreme programming, which he has been practising for about two years. To Discuss this article: http://forums.phparch.com/235 57 R E V I E W PR O DUCT R EV IE W PDF Generation Library P R O D U C T by Peter B. MacIntyre H ave you ever wanted to make dynamic PDF files for your web customers? This month’s review will be covering the latest release of the FPDF library for PHP. Most of my reviews so far have been to look at screen shots of the development environment of the tool or product in question. This review will be looking at more code examples and some rudimentary examples of what can be accomplished with the FPDF library. I usually introduce the product with a little quote from their web site, so let’s not stray too far from our comfort zone–here is what the FPDF library web site has to say about its own product. generate PDF files with pure PHP... F from FPDF stands for Free: you may use it for any kind of usage and modify it to suit your needs. FPDF has other advantages: high level functions. Here is a list of its main features: “FPDF is a PHP class which allows to July 2005 ● PHP Architect ● www.phparch.com • Choice of measure unit, page format and margins • Page header and footer management • Automatic page break • Automatic line break and text justification • Image support (JPEG and PNG) PRODUCT INFORMATION PHP 4+ OS Any Product Version 1.53 Price FREE! Web Address http://www.fpdf.org 58 PR ODU CT R EV IE W FPDF: PDF Generation Library • Colors • Links • TrueType, Type1 and encoding support Page compression FPDF requires no extension (except zlib to activate compression) and works with PHP4 and PHP5.” As you can see, this library thinks quite highly of itself. So, let’s get into it and see what it can actually do. First Things First Let’s first take a look at how to install this library. To be clear this is not a library in the true sense of the term in that you have to adjust your php.ini file and re-start your web server to make it work. This is a class library and by that definition all you need to do is to add a require call to the script that will be using the FPDF class. To install this class, simply download the file and un-compress it in its own folder at the top level of your web server. For example, on Windows with a standard Apache install, you would place the files in a folder called FPDF under the htdocs folder. Putting the class definition files at this level will allow you to make use of the library from any web project more easily. With the installation complete, let’s look at a starting example. The following PHP code should generate a standard, simple text output to the web browser of your choice in PDF format (and since I hate the “Hello World” examples, I am say- Figure 1 ● The output of this code running on my local server is shown in Figure 1. As you can see, after the fpdf.php file is required, a new object instance is created. Then, a page is created in the class, a font and a cell is defined. Finally, the generated material is sent to the browser with the Output() method call. The only half-difficult thing to look at in this code is the cell call and its features. The cell is a defined area on the PDF page, with coordinates starting on the top left of the page. The cell definition then creates a cell with a width of 70 millimeters and a height of 10 millimeters. These dimensions can be adjusted in the creation of the class, but we are using the defaults here. The other measurement options are points, centimeters, and inches. So, What Else..? Now, let’s take this to the next stage and show you some more of what this product can do for you. Let’s add some headers and footers to the page and add a second page to show you how this can all be done. At the same time, the code will create two columns on the page. Since this tool is object based, it lends itself to be extendible as any class can be extended in PHP. I mention this because the page header and page footer methods are automatically called when the AddPage() method is called. They are empty ancestor methods by default, so we have to Figure 2 July 2005 ing “Greetings Architect Readers!” instead). Keep in mind that this is a PDF generation library and therefore your browser should have the Acrobat Reader installed on it at the least. PHP Architect ● www.phparch.com 59 PR O DUCT R EV IE W FPDF: PDF Generation Library extend them and add content to them. Then, the code will be called as before. Two other methods are also defined so that the columns can be controlled. Listing 1 shows this code for you with a header and footer defined, and the column managing methods. This code also defines the overall PDF page parameters in this line of code: $pdf=new myPDF(‘P’,’mm’,’Letter’); Here, we are defining a portrait (‘P’) style page, with measurements in millimeters (‘mm ’), and the Letter page size. The output from Listing 1 is as shown in Figure 2. This sample code was taken and modified from the on-line tutorial at the FPDF web site. There are some other samples up there, with even more in that web site’s forum section. I have just scratched the proverbial surface, here and the additional samples on the web site will give you lots more to think about and show you what is really possible. Summary FPDF is a very stable and extendible product. The fact that it is open source is certainly an added bonus. The help and samples that are available on the web site are a great supplement to learning. If you want to generate dynamic PDF documents in PHP, then this is the answer. I give this product 4.5 out of 5 stars. About the Author ?> Peter MacIntyre lives and works in Prince Edward Island, Canada. He has been and editor with php|architect since September 2003. Peter’s web site is at http://paladin-bs.com July 2005 ● PHP Architect ● Listing 1 1 86 www.phparch.com 60 CLASSROOMS VIRTUAL Online Training Courses from php|architect Zend PHP Essentials Our introductory PHP course, Zend PHP Essentials, was developed for us and Zend Technologies by PHP expert Chris Shiflett, co-founder of the PHP Security Consortium. This 19-hour course provides a thorough introduction to PHP development, with particular care to "doing things right" by covering security, performance and the best development techniques. Rather than cramming as much theory as possible, PHP Essentials provides a thoroughly practical approach to learning PHP—thus ensuring that each student will be able to write good PHP code in a real-world setting by the end of the course. Zend PHP Certification Training Zend Professional PHP Development If you want to become a Zend Certified Engineer, this course is the best preparation tool that you'll ever find! Designed by some of the same Subject Matter Experts who also helped write the exam itself, this course covers every single topic that is part of the exam. The Zend PHP Certification Training (course) provides a complete overview of the exam, and doubles as an excellent refresher course in PHP for any developer. This is our advanced course for the professional PHP developer. This course picks up from where PHP Essentials ends and provides a thorough, in-depth analysis of advanced features found in both PHP 4 and PHP 5, including object-oriented programming and design patterns, XML development, regular expressions, encryption, e-mail manipulation, performance management and advanced databases. Course Description Zend PHP Essentials • Covers PHP 4 and PHP 5 • July 12 • Provides a thorough practical • August 8 introduction to PHP • September 5 • Covers security and performance 7 Sessions 19 Hours 3 Weeks YES - $769.99 US ($999.99 CAD) Zend PHP Certification Training • Covers every topic in the exam • Provides an excellent refresher course for PHP at all levels • July 6, • August 1 • September 1 7 Sessions 19 Hours 3 Weeks YES Zend PHP Essentials $644.99 US ($838.99 CAD) • July 7, • August 11 • September 6 7 Sessions 19 Hours 3 Weeks YES Zend PHP Essentials $769.99 US ($999.99 CAD) • Covers advanced PHP 4 and PHP 5 topics Zend Professional • Perfect for going "beyond the PHP Development basics" and learning the true Start Dates Duration Tutoring Prerequisites Cost power of PHP • All our courses are delivered entirely online using an innovative system that combines the convenience of the Internet with the unique experience of being in a real classroom. • All sessions take place in real time, and the students can interact directly with the instructor as if they were in a real classroom either via voice or text messaging. • In most cases, our system requires no software installation and works with the majority of operating systems and browsers, including Windows, Mac OS and Linux, as well as Internet Explorer, Firefox and Safari. • All courses include a generous amount of homework and in-class exercises to ensure that the students assimilate each topics thoroughly. • Tutoring is available (via e-mail) throughout the duration of the entire course. • Each class includes a complete set of recordings that the students can peruse at their leisure. For more information, visit our website at http://www.phparch.com/phptraining or call us toll-free at (877) 630-6202 (416-630-6202 outside Canada and the U.S.) S E C U R I T Y C O R N E R SE CUR ITY COR N ER Security Corner Theory by Chris Shiflett Welcome to another edition of Security Corner. This month’s topic is “theory,” an important characteristic of the web application security discipline. Professional PHP developers tend to be pragmatic, and this pragmatism helps them solve problems quickly and directly. However, without a strong theoretical foundation, developers often produce solutions that are slow, unreliable, hard to maintain, or insecure. As a language, PHP is often criticized for the shortcomings of its developers. Of course, those of us within the community know that these criticisms have little merit. Rather than bemoan the ignorance of the naysayers, however, I want to discuss theory as it relates to developing secure PHP applications. I was in Vancouver recently to give a talk at PHP West called the PHP Security Audit HOWTO. The positive response has been overwhelming, which is unusual—I typically receive very little feedback from any of my talks (or articles, for that matter). While trying to determine the reason for the increased positive response, I have decided that it is mostly a result of the talk being more pragmatic than my others. Rather than giving sound theoretical advice, the talk mostly consists of me explaining specific strings that you can search for in your PHP July 2005 ● PHP Architect ● code in order to focus on common points of failure and quickly locate potential security weaknesses. Many slides simply list a collection of related strings to search for, and I discuss the common mistakes that I have observed the most. As a result of this observation, I have decided to write a brief explanation about why theory is important to security. I am not trying to convince you to be less pragmatic. On the contrary, I want you to embrace your pragmatism while still adhering to some theoretical practices that have been known to have practical effects. Remember, being stubborn has nothing to do www.phparch.com with being pragmatic. Defense in Depth One of my favorite security principles is Defense in Depth. This principle asserts that redundant safeguards have value. Stated differently, you can never be too safe. The idea is pretty simple, but let me give you a practical example. If I am writing an application that lets users register, I might have a form that accepts a username, password, and email address. If I only allow alphanumeric usernames, I can enforce this in my input filtering: Once assured that I have a valid username, I might store it in the user’s session: Knowing that session data is stored on the server, I know that it’s pretty trustworthy, at least compared to data coming from the client or some other external source. Therefore, I might choose to greet the user on each page: If you are a regular reader of Security Corner, you should know that output must always be escaped: Astute readers might already be questioning me, noting that htmlentities() is going to have no effect on an alphanumeric string. The username has no special characters that need to be escaped, so this extra work is useless. The truly pragmatic developers might even be disgusted by such an approach. The time it took to write those extra few lines of code could have been applied to solving the next problem. These arguments and criticisms all have merit, and that is often the dilemma I am faced with when discussing the theoretical aspects of security. History has demonstrated that theoretical weaknesses often yield real vulnerabilities in time, and this is the primary reason why adhering to theoretically sound practices can save you from attacks that are either unknown or which do not yet exist. In this particular example, there are situations that can yield a cross-site scripting vulnerability if the escaping is not performed. For example, the session data store might be compromised (a trivial task in many cases), so that $_SESSION[ ‘username’] is no longer the filtered username but rather some tainted data. If the seemingly useless escaping step is taken, it can potentially save the day. This is the idea of Defense in Depth, and this demon- July 2005 ● PHP Architect ● www.phparch.com strates the general idea of theoretical security. Complex systems can behave in unknown ways, and there is a great deal of value in checking this behavior and enforcing certain restrictions, even when your effort seems redundant and wasteful. Never Correct Invalid Data There is another principle of security that points out the dangers of modifying invalid data in an attempt to make it valid. (It is not as well known as Defense in Depth, most likely because there is no standard name for it.) This goes against the natural instinct of many PHP developers, and it requires a strong commitment to theory in order to fully appreciate. The idea is simple—input filtering is an inspection process, not a modification process. I see developers using many techniques that conflict with this principle. For example, you might want to be sure that $_GET[‘id ’] is an integer: Is this safe? The answer isn’t so straightforward. In this particular example, there is no vulnerability introduced. However, it does hide malicious attempts, so you aren’t kept aware of the fact that your application is being attacked. You could correct this by first inspecting the data and logging all data that fails your inspection, but then you might as well use that as your input filtering. (Doing both is a good Defense in Depth strategy, but only because the intval() function should have no affect.) A better example of trying to correct invalid data is when developers manually attempt to eliminate file traversal vulnerabilities: The idea here is simple. For every reference to the parent directory, it is replaced with a reference to the current directory. However, imagine that $_POST[‘filename ’] contains the following: .../.../.../.../.../etc/passwd This would be easy to identify as invalid input. However, because an attempt is made to correct the invalid data, $clean[ ‘filename’ ] becomes the following: ../../../../../etc/passwd This particular vulnerability could have been resolved by performing the same string replacement until a reference to the parent directory is no longer found (using 64 SE CUR ITY COR N ER a while loop, for example), but the point is that it’s dangerous to try to correct invalid data. It’s always safer to inspect the data and ensure that it abides by your rules. If it does not, then it’s better to force the user (or other external system) to supply you with valid data rather than try to correct the invalid data. Doing otherwise heightens your risk, and a mistake can be disastrous. Frequent Debates There are other debates that I observe quite frequently within the community, and it’s almost always a result of someone being stubborn. For example, a common debate is whether htmlentities() is really any safer than just replacing angled brackets with their HTML entities: This particular example has another problem, because it fails to filter input ($_POST[ ‘username’ ]), but the escaping is also sub-par. This is difficult to prove, because examples that exploit this approach are complex. When I want to explain to someone why they should not echo the raw $_POST[‘username’], I can supply a simple example that they can understand: “><script>alert(‘XSS’) Chris Shiflett is an internationally recognized expert in the field of PHP security and the founder and President of Brain Bulb, a PHP consultancy that offers a variety of services to clients around the world. Chris is a leader in the PHP industry, and his involvement includes being the founder of the PHP Security Consortium, the founder of PHPCommunity.org, a member of the Zend PHP Advisory Board, and an author of the Zend PHP Certification. A prolific writer, Chris has regular columns in both PHP Magazine and php|architect. He is also the author of the HTTP Developer's Handbook (Sams) as well as the highly anticipated PHP Security (O'Reilly). You can contact him at [email protected] or visit his web site at http://shiflett.org/. 65 You’ll never know what we’ll come up with next For existing subscribers NEW Upgrade to the Print edition and save! LOWER PRICE! Login to your account for more details. php|architect Visit: http://www.phparch.com/print for more information or to subscribe online. The Magazine For PHP Professionals php|architect Subscription Dept. P.O. Box 54526 1771 Avenue Road Toronto, ON M5M 4N5 Canada Name: ____________________________________________ Address: _________________________________________ City: _____________________________________________ State/Province: ____________________________________ 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. WR PRICE! E N WE *US Pricing is approximate and for illustration purposes only. Choose a Subscription type: Canada/USA International Air Combo edition add-on (print + PDF edition) LO $ 77.99 $105.19 $ 14.00 CAD CAD CAD ($59.99 ($80.89 ($10.00 US*) US*) US) ZIP/Postal Code: ___________________________________ Country: ___________________________________________ Payment type: VISA Mastercard American Express Credit Card Number:________________________________ Expiration Date: _____________________________________ Signature: Date: *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. E-mail address: ______________________________________ Phone Number: ____________________________________ 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 E XIT( 0) ; Forget Viagra Get a Regex e x i t ( 0 ) ; by Marco Tabini I ’ve always thought of regular expressions as the third rail of computer programming—one often cannot make do without the power they provide, but, once you’ve written one, touch it and die. I have seen regular expressions so perversely complicated that it’s no wonder many programmers prefer to do away with them altogether and take refuge in replacing them with their own code—which is usually even more complicated than the regular expression it sought to replace in the first place, but at least more readable. There hasn’t been a good reason why this should be the case for a long time. Regular expressions can be written using an “extended” syntax that makes it possible to insert plenty of white space and comments, and yet most people prefer to use the “normal” syntax and write expressions that look like the spurious dying signals sent to the computer by a keyboard on fire. There doesn’t seem to be any explanation for this phenomenon other than the fact that programmers must get a rush from writing regular expressions with the knowledge that no one else in the known universe (including themselves fifteen minutes later) will ever be able to understand them without going completely insane. Better yet, I July 2005 ● PHP Architect ● have the feeling that some developers may be abusing regexes as a cheap substitute for Viagra. If you do and it works, please drop me a line and let me know—we may be able to open a new online store. In case you don’t, let me give you a simple example of what I mean. A few days ago, I was looking for a regex that would allow me to highlight keywords within an HTML file. The task is not as simple as it sounds, because the keyword may be right in the middle of a URL, in which case you definitely don’t want to insert further HTML code to highlight it in there. As those who follow my articles know, I am lazy. I am also not a particularly good regex developer (in fact, I know some who would maliciously claim that I am not a particular developer at all, but that’s another story); therefore, before trying to come up with a solution myself, I decided to look around the PHP manual, where I found exactly what I was looking for in one of the notes to preg_replace(). Here’s a small excerpt from that expression (the whole thing would require a much longer article than I’m allowed these days): /( \>( ((? >[^ > ( # match a literal > ( (?> # [^> or recurse subpattern zero or more times followed by a literal Recommend Documentsed sh itin ari g ng
IT Schools Ranked
o eBanking at work ot ph
TOP 11
blogging
01 02 03 04 05 06 07 08 09 10 11 12 ...
Innovative Technology for Computer Professionals
July 2005
Judging Science Fairs, p. 12 Timeliness in Networked Embedd...
www.computing.co.uk
Happy Ever after
The war on ID theft
Top jobs
Everton enters the new season with a revamped sys...
The Economist - North America Edition Jul 16th 2005
TeAM YYePG Digitally signed by TeAM YYePG DN: cn=TeAM YYePG, c=US,...
The Economist - North America Edition Jul 30th 2005
TeAM YYePG Digitally signed by TeAM YYePG DN: cn=TeAM YYePG, c=US,...
In This Issue
July 2005 In This Issue Click article title to open Reviews
People
Arturia Minimoog V
Crosstalk: Your ...
signed-by TheDigitally Economist Asia Pacific Edition TeAM YYePG Jul 2nd 2005 DN: cn=TeAM YYePG, c=US, o=TeAM YYePG, ou...
The Economist - North America Edition Jul 9th 2005
TeAM YYePG Digitally signed by TeAM YYePG DN: cn=TeAM YYePG, c=US, ...
The Economist - North America Edition Jul 23rd 2005
The world this week Politics this week Business this week
Letter...
Sign In
Our partners will collect data and use cookies for ad personalization and measurement. Learn how we and our ad partner Google, collect and use data. Agree & close
|