VOLUME III - ISSUE FEBRUARY 2004 The Magazine For PHP Professionals PROFILING PHP Understand and optimize your code ] ] W riting an SMS G ateway w ith PHP and G nokii EXtending PHP Handling PHP Arrays from C Caching Techniques for the PHP Developer The Need for Speed www.phparch.com Writing More efficient PHP scripts Offline News Management with PHP-GTK Get Ready For php | Cruise See inside for details Plus: March 1st - March 5th 2004 Tips & Tricks, Security Corner, Product Reviews and much more In partnership with Zend Technologies Zend Studio 3.0 is the official PHP IDE of php|cruise We’ve got you covered, from port to sockets php | Cruise Port Canaveral • Coco Cay • Nassau March 1st - March 5th 2004 Signup deadline: Feb 15, 2004 ENJOY LEARNING PHP IN A FUN AND EXCITING ENVIRONMENT—AND SAVE A BUNDLE! Features Visit us at www.phparch.com/cruise for more details Andrei Zmievski - Andrei's Regex Clinic, James Cox - XML for the Masses, Wez Furlong - Extending PHP, Stuart Herbert - Safe and Advanced Error Handling in PHP5, Peter James - mod_rewrite: From Zero to Hero, George Schlossnagle Profiling PHP, Ilia Alshanetsky - Programming Web Services, John Coggeshall Mastering PDFLib, Jason Sweat - Data Caching Techniques Plus: Stream socket programming, debugging techniques, writing high-performance code, data mining, PHP 101, safe and advanced error handling in PHP5, programming smarty, and much, much more! php | Cruise Conference Pass $ 899.99** Hotel Traditional PHP Conference* Included Meals Totals: $ 1,150.00 ($ 400.00) Included*** $ 899.99 ($ 200.00) $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 TABLE OF CONTENTS php|architect Departments Features Editorial Write SMS Applications With PHP and Gnokii by Eric Persson I N D E X What’s New! 16 37 Offline Content Management with PHP-GTK Product Review by Morgan Tocker SQLyog 23 58 Writing PHP Extensions: Managing Arrays Product Review 2003 Quebec PHP Conference DVD by Marco Tabini by Wez Furlong 28 61 The Need For Speed by Chris Shiflett 65 Security Corner Optimizing your PHP Applications by Ilia Alshanetsky Tips & Tricks By John W Holmes 41 Profiling PHP Applications by George Schlossnagle 68 exit(0); Why Can’t We All Just Get Along? By Marco Tabini 51 Caching Techniques for the PHP Developer by Bruno Pedro February 2004 ● PHP Architect ● www.phparch.com You’ll never know what we’ll come up with next ! EW N Existing subscribers can upgrade to the Print edition and save! 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: ZIP/Postal Code: _ Your charge will appear under the name "Marco Tabini & Associates, Inc." Please allow up to to weeks for your subscription to be established and your first issue to be mailed to you *US Pricing is approximate and for illustration purposes only Choose a Subscription type: Canada/USA International Surface International Air Combo edition add-on (print + PDF edition) $ 83.99 $111.99 $125.99 $ 14.00 CAD CAD CAD CAD ($59.99 ($79.99 ($89.99 ($10.00 US*) US*) US*) US) Country: _ Payment type: VISA Mastercard American Express Credit Card Number: Expiration Date: _ E-mail address: Phone Number: 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 **Offer available only in conjunction with the purchase of a print subscription 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 EDITORIAL E D I T O R I A L R A N T S W elcome to the February 2004 issue of php|architect As I write this, I'm sitting in my office—about forty degrees Celsius warmer than outside and, therefore, a much better place to work in that that the local park—suffering from an awful cold and sitting by a collection of (clean) tissues discreetly stashed on my desk, ready for use As you can expect, I'm not particularly happy about either fact (make that three facts—the cold outside, the cold in my body, and the fact that I'm sitting in an office when I could really be somewhere else far away from anything that even remotely resembles a computer) Incidentally, with php|cruise coming at the beginning of March, I should hopefully be able to get rid of at least two problems—and I'm still working on finding a way to avoid computers during that trip But I ramble—a clear sign that the cold medicine is wearing off Let me instead tell you something about this month's issue With the popularity that PHP enjoys nowadays comes the fact that it is used as the backbone of more and more high-traffic sites A simple consequence of this is that an increasing number of developers are "hitting the wall" and finally feeling the limits of what the "let's just it in PHP" approach can Building a website is always a high-wire balance of budgeting, respecting deadlines and writing the best code possible, but there's nothing quite as bad as finding out that the way you've done things is incapable of meeting the demands of your website—and, by the time you realize that you have a problem, it's usually too late to think about a solution short of calling your travel agent and inquiring about that non-extradition country you heard of Therefore, this month we dedicate a fair amount of room to the performance management of PHP applications George Schlossnagle's article—based on an excerpt from his latest book, published by SAMS—talks about profiling, a concept that I have very rarely seen associated with PHP applications Profiling takes the guesswork out of understanding where the bottlenecks in your application are, allowing you to focus on finding the best possible resolution The problem with profiling is that it only allows you to identify the problems and not solve them Luckily, Ilia Alshanetsky and Bruno Pedro offer two other excellent articles on improving the performance of PHP without affecting the code itself (if you can, why not avoid the risk of introducing even more bugs?) While Ilia focuses on ways to make the PHP interpreter itself run faster, Bruno examines the topic of caching—both at the network and script level This month we also start a new column—Security Corner—written by Chris Shiflett The daily number of security advisories, patches, break-ins and source-code thefts that we see reported in the media every day has Continued on page February 2004 ● PHP Architect ● www.phparch.com php|architect Volume III - Issue February, 2004 Publisher Marco Tabini Editorial Team Arbi Arzoumani Peter MacIntyre Eddie Peloke Graphics & Layout Arbi Arzoumani Managing Editor Emanuela Corso Director of Marketing J Scott Johnson scott@phparch.com Account Executive Shelley Johnston shelley@phparch.com Authors Ilia Alshanetsky, Wez Furlong, John Holmes, Bruno Pedro, Eric Persson, George Schlossnagle, Chris Shiflett, Morgan Tocker php|architect (ISSN 1709-7169) is published twelve times a year by Marco Tabini & Associates, Inc., P.O Box 54526, 1771 Avenue Road, Toronto, ON M5M 4N5, Canada Although all possible care has been placed in assuring the accuracy of the contents of this magazine, including all associated source code, listings and figures, the publisher assumes no responsibilities with regards of use of the information contained herein or in all associated material Contact Information: General mailbox: info@phparch.com Editorial: editors@phparch.com Subscriptions: subs@phparch.com Sales & advertising: sales@phparch.com Technical support: support@phparch.com Copyright © 2003-2004 Marco Tabini & Associates, Inc — All Rights Reserved NEW STUFF N E W S T U F F What’s New! PHP 4.3.5 RC1 PHP.net has announced the release of PHP 4.3.5 RC1 PHP 4.3.5RC1 has been released for testing This is the first release candidate and should have a very low number of problems and/or bugs Nevertheless, please download and test it as much as possible on real-life applications to uncover any remaining issues List of changes can be found in the NEWS file For more information visit: http://qa.php.net/ PHP Community Logo Contest Following Chris Shiflett’s recent announcement of the PHP Community Site, he is holding a contest to find a logo that embodies the spirit of the PHP community Everyone is welcome to participate, and you can submit as Many entries as you like Please send all entries to logos@phpcommunity.org And include the name with which you want to be credited The contest ends 29 Feb 2004, and php|architect is offering a free PDF subscription to the winner For updated news about the contest, as well as a chance to view the current entries, visit: http://www.phpcommunity.org/logos/ ZEND Studio 3.0.2 Zend has announced the release of Zend Studio 3.0.2 client What’s new? Zend.com lists some of the bug fixes as: • ZDE didn’t load when using a new keymap config from an older version • Save As Project didn’t always work • Server Center activator tried to open the wrong URL • js files were not opened with JavaScript highlighting • Shift-Delete and Shift-Backspace didn’t work properly • Find&Replace was very slow under Linux • Add Comment sometimes erroneously commented out a line that wasn’t selected • Added configurable limit for the number of displayed syntax errors There have also been improvements to the debugger, code completion, code analyzer, IE toolbar, and some Mac OSX changes Get more information from Zend.com Good luck to all who enter! February 2004 ● PHP Architect ● www.phparch.com NEW STUFF MySQL Administrator MySQL.org announces: MySQL Administrator is a powerful new visual administration console that makes it significantly easier to administer your MySQL servers and gives you better visibility into how your databases are operating MySQL Administrator integrates database management and maintenance into a single, seamless environment, with a clear and intuitive graphical user interface Now you can easily perform all the command line operations visually, including configuring servers, administering users, dynamically monitoring database health, and more Get more information from: http://www.mysql.com/products/administrator/index.html Looking for a new PHP Extension? Check out some of the latest offerings from PECL Check out some of the hottest new releases from PEAR opendirectory 0.2.2 Open Directory is a directory service architecture whose programming interface provides a centralized way for applications and services to retrieve information stored in directories The Open Directory architecture consists of the DirectoryServices daemon, which receives Open Directory client API calls and sends them to the appropriate Open Directory plug-in DB 1.6.0 RC4 DB is a database abstraction layer providing: statgrab 0.1 libstatgrab is a library that provides a common interface for retrieving a variety of system statistics on a number of *NIX like systems This extension allows you to call the functions made available by libstatgrab library Sasl 0.1.0 SASL is the Simple Authentication and Security Layer (as defined by RFC 2222) It provides a system for adding plugable authenticating support to connection-based protocols The SASL Extension for PHP makes the Cyrus SASL library functions available to PHP It aims to provide a 1-to-1 wrapper around the SASL library to provide the greatest amount of implementation flexibility To that end, it is possible to build both a client-side and serverside SASL implementation entirely in PHP SQLLite 1.0.2 SQLite is a C library that implements an embeddable SQL database engine Programs that link with the SQLite library can have SQL database access without running a separate RDBMS process This extension allows you to access SQLite databases from within PHP Windows binary available from: http://snaps.php.net/win32/PECL_STABLE/p hp_sqlite.dll February 2004 ● PHP Architect ● www.phparch.com • an OO-style query API • a DSN (data source name) format for specifying database servers • prepare/execute (bind) emulation for databases that don’t support it natively • a result object for each query response • Compatible with PHP4 and PHP • much more… DB layers itself on top of PHP’s existing database extensions The currently supported extensions are: dbase, fbsql, interbase, informix, msql, mssql, mysql, mysqli, oci8, odbc, pgsql, sqlite and sybase (DB style interfaces to LDAP servers and MS ADO (using COM) are also avaible from a separate package) System_ProcWatch 0.4 With this package, you can monitor running processes based upon an XML configuration file, XML string, INI file or an array where you define patterns, conditions and actions Net_IMAP 0.7 Provides an implementation of the IMAP4Rev1 protocol using PEAR’s Net_Socket and the optional Auth_SASL class XML_Beautifier 1.1 XML_Beautifier will add indentation and line breaks to you XML files, replace all entities, format your comments and makes your document easier to read You can influence the way your document is beautified with several options NEW STUFF PHPWeather 2.2.1 PHP Weather announces the release of version 2.2.1 PHP Weather makes it easy to show the current weather on your webpage All you need is a local airport, that makes some special weather reports called METARs The reports are updated once or twice an hour Get more information from : http://sourceforge.net/projects/phpweather/ PHPEclipse Debugger PHP Eclipse adds PHP support to the Eclipse IDE Framework This snapshot introduces the first version of the PHPEclipse debugger plugin For more information visit: http://www.phpeclipse.de MySQL and Zend Working Together From Zend and MySQL – These two have Joined Forces to Strengthen Open Source Web Development MySQL AB, developer of the world’s most popular open source database, and Zend Technologies, designers of the PHP Web scripting engine, today announced a partnership to simplify and improve productivity in developing and deploying Web applications with open source technologies Through the alliance, the companies are improving compatibility and integration between the MySQL database and Zend’s PHP products to make it easier for businesses to use complete open source solutions, such as the popular LAMP (Linux, Apache, MySQL and PHP) software stack As part of the partnership, MySQL AB and Zend are offering partner products to their respective customers, enabling easier product procurement and deployment for Web application infrastructures The companies will also commit development resources to design product integration and compatibility modules for both vendors’ platforms For more information visit: www.zend.com SAXY 0.3 SAXY is a Simple API for XML (SAX) XML parser for PHP It is lightweight, fast, and modeled on the methods of the Expat parser for compatibility The primary goal of SAXY is to provide PHP developers with an alternative to Expat that is written purely in PHP Since SAXY is not an extension, it should run on any Web hosting platform with PHP and above installed This release allows CDATASection tags to be preserved, rather than converted to Text Nodes For more information visit: http://www.engageinteractive.com/saxy/ php|a Editorial: Contiuned from page convinced us that, at the very least, one should be able to protect his sites from malicious usage, in the hope that all the other companies we rely on to maintain their software will so in a serious way Finally, we bring you three more articles that, we hope, will tickle your fancy The first one, written by Eric Persson, shows you how you can build an SMS gateway using PHP and a few other inexpensive components SMS is not yet very popular here in North America, but, judging from the amount of people I see glued to their cell phones whenever I visit my native Italy, it is very widely used in Europe In his article on offline news management, Morgan Tocker writes about how PHP-GTK, that most hidden of PHP gems, can be used to improve content management by providing a proper GUI application that doesn't require you to completely rewrite all your code Finally—last but not least-Wez Furlong picks up where his article from last month left off and delves into the deep bowels of the Zend Engine to show you how a PHP extension written in C can manipulate PHP arrays— it's not quite as easy as from a script but close enough once you know what you're doing Well, that's it for this month By the time I will be writing my next editorial, I plan to be either boasting about my suntan or complaining about sunburn Either way, you can expect me to report on our adventure on the high seas—until then, happy reading! February 2004 ● PHP Architect ● www.phparch.com Write SMS Applications With PHP and Gnokii F E A T U R E by Eric Persson SMS-shorthand for Short Message Service-is the standard used by cellular phone networks worldwide to allow their customers to exchange small text messages using their handsets Despite its limitations, SMS is very popular with cell phone users-and it has rapidly become a widely-used bridge between the Internet and mobile users espite the fact that it sounds like some mysterious Italian pasta, Gnokii is really just a project aimed to develop tools and drivers for Nokia mobile phones-that is, software that makes it possible to control a Nokia phone physically connected to your server via a serial port Gnokii works like the Nokia Data Suite, which is shipped with more advanced models from Nokia: you can use it to send SMS messages, edit contacts and so on—pretty much everything you normally with your thumb on the phone's keypad Gnokii itself is composed of many tools, including a set of GUI applications that facilitate the remote operation of the telephone; we are really only interested in a small subset of these tools called smsd, or SMS daemon, which provides an interface for rapid access to the phone's SMS capabilities With the SMS daemon up and running, we can use PHP to interact with the phone, send and receive SMS messages and, of course, build whatever logic we need based on the content of the messages that we receive and send In short, my goal with this article is to show you how to configure software and hardware so that you can get the same kind of service as you would normally obtain from a big company selling mobile services like SMS gateways— but at a fraction of the price three major components: Major Components of the Final Application The final application that we will create throughout this article is a simple SMS server that awaits a message from a user and acts on its contents It is made up of PHP: 4.1 or higher OS: Unix/Linux Applications: Gnokii (http://www.Gnokii.org) Code: http://code.phparch.com/20/3 Code Directory: sms-gnokii D February 2004 ● PHP Architect ● www.phparch.com • A Nokia cell phone, which must be connected properly to the server • The smsd application from the Gnokii package, which must, of course, be compiled and configured correctly • The PHP scripts that provide the actual server functionality The flow of the application will be as follows: • The user send an SMS message to the server • The smsd daemon picks it up and automatically puts it into its database • Our server scans smsd's database periodically for new messages • When a new message arrives, its contents are examined and the server acts on them, for example by replying to the user with another message REQUIREMENTS FEATURE Caching Techniques for the PHP Developer can save the output for later reuse by caching it Naturally, this approach only works if the data doesn't change too often between requests There are many available ready-to-use solutions for content caching with PHP, some of which not even require you to write a single line of code The most interesting, however, are those that you can use from within your scripts to accurately manage your caching needs PEAR includes two packages for this purpose that are very popular: • PEAR::Cache_Lite-probably the easiest to use and adequate for most jobs • PEAR::Cache-the most popular and very complete, good for large projects The PEAR::Cache_Lite version is very straightforward to use and, although "lite", it is nevertheless able to the Listing 2 10 11 12 13 14 15 16 17 18 19 20 job just fine If you have access to PEAR you can install it by issuing the following command: # pear install Cache_Lite The main goal of the Cache_Lite package is, of course, simplicity For this reason, cached content is only stored in files, and the caching class is optimized for that purpose For safety reasons, Cache_Lite also implements file locking, and read/write controls You use Cache_Lite by creating a new object and reading and writing data to it The class constructor accepts an array of options through which you can specify, for example, the directory where the cache files will be saved and what the cache lifetime in seconds will be Take a look at the example in Listing As you can see, once the cache object is initialized, all we have to is use the save() method to store information in it, and then use get() to retrieve it—what could be simpler? If you need a higher level of control over your caching activities-and if you want to take advantage of some more advanced features—PEAR's Cache package (the full version) offers a more complex (and complete) framework for the caching of dynamic content, database queries, and PHP function calls This tool is made up of a generic cache class and many specific containers, which define the way the cache data is handled This means that the degree of freedom you have over what happens to your cached content is excellent You can, for example, save the cache data in a MySQL database as easily as in a local file—it's simply a matter of Listing Listing 3 10 11 12 13 14 15 10 11 12 13 14 15 16 Listing 4 10 11 12 13 14 15 16 17 18 February 2004 ● PHP Architect ● www.phparch.com Listing 6 10 11 12 13 14 15 16 17 55 FEATURE Caching Techniques for the PHP Developer choosing the right container If you take a look at Listing 2, you'll see that it's not all that different from the Cache_Lite example above and, indeed, if all you needed to was a simple operation like the one in this example, you would probably be better off using the simpler package Let's now look at some other examples of content caching strategies For example, consider a technique known as "function call caching" It works by saving the result and the output of a function call and reusing it until the timeout associated with the cached content is reached In this case, to make the cache aware of your intentions, you have to use a special wrapper instead of calling functions directly The script in Listing 3, for example, uses the call method of PEAR::Cache_Lite to illustrate this concept Take note that both the output and the result (what is return'ed) of the function are cached You can also cache object methods, regardless of whether they are dynamic or static, as you can see in Listing In this particular instance, if you wanted to call yourMethod statically, you would simply have to change the $cache>call() method call to the following: $cache->call('YourClass::yourMethod', $arg1, $arg2); Output caching The final caching technique that we will be looking at in this article is output caching, consists of buffering the output of a block of code (or the entire script) and then utilizing it as a cache for your content The main advantage of using this method, compared the other ones we looked at, is that coding is much faster because you only need to "enclose" the code block you wish to cache within a series of specific caching instructions The example in Listing uses Cache_Lite_Output to demonstrate this technique As you can see, there really isn't much to it All you is call the start() method to initialize the cache (or cause the cached content to be output if the cache was previously initialized and it has not yet reached its time-to-live) and then call the end() method inside your if-then-else code block to instruct the caching mechanism as to where it should stop recording data This caching approach can be extremely powerful if properly used For example, you could even write an auto_prepend script which would automatically cache all the PHP scripts in your site What's even more impressive is that you only really need a few lines of code to this Start with the code in Listing 6, which you can save as prependScript.php This script performs similarly to the one in Listing 5—the only difference is in the fact that, if cached content is not available, it "includes" the script that should be executed, so that its output can be buffered You can now configure PHP to use the previous file as an auto_prepend script Edit your httpd.conf or htacFebruary 2004 ● PHP Architect ● www.phparch.com cess file and add the following line: php_value auto_prepend prependScript.php Once you restart Apache (if needed), the interpreter will execute the code in Listing right before it runs any script invoked through the web server, thus causing our little caching scheme to enter into the picture and, effectively, cache the output of every dynamic page in the site Naturally, such a blanket approach will not work well under all circumstances, but you could customize the procedure so that the cache ID would change according to the script name, and maybe change the cache timeout based on some configuration parameters that take into account the actual requirements of your website A Look at Cache Containers Cached objects must be stored somewhere so that they can later be retrieved and used, such as the hard drive, or your computer's memory Every medium has its advantages and disadvantages, so that you'll have to choose the one that best suits your needs The three containers that are used most often are files, databases and shared memory Files are, by far, the most common of the three, and the only choice at your disposal if you use Cache_Lite Their biggest drawback is that they are relatively slow, but they have the advantage of being simple to use without hogging down any of your other system resources, like memory or database availability Both PEAR::Cache and PEAR::Cache_Lite use file locking to prevent data corruption However, be aware that PEAR::Cache's locking implementation is experimental and is, therefore, turned off by default Database containers are useful when you have many front-ends using the same cache store You could, of course, still use a file-based cache through a partition shared over your local network but, in some cases (for example if you use NFS), file handling can become ineffective because of lock restrictions and cause all sorts of problems In these circumstances, a database becomes a viable alternative; MySQL is, of course, the most popular backend for this type of operations because of its widespread availability and good performance Finally, the last option that we'll discuss here is shared memory As its name implies, it is, essentially, an area of memory that is shared across multiple processes running on the same machine Even though using RAM often results in a very high data throughput, caching with PEAR and shared memory is not quite as fast as one would expect In fact, you'll find that the PEAR::Cache shared memory implementation is actually slower than the file container, mostly because the operating system already implements a memory cache for file operations, and it's hard to beat its performance from PHP 56 FEATURE Caching Techniques for the PHP Developer A Few Parting Thoughts All the techniques that we have examined in this article can be combined for maximum performance Opcode caches can make your scripts more responsive, while content caching can easily solve bottlenecks that depend on external factors beyond your control By adding network caching to the mix, you ensure that clients will only request content from your server as appropriate, thus reducing your load and increasing your ability to serve more clients There are, of course, restrictions to the use of caching techniques You should first benchmark your site to find out where the bottlenecks are and what kind of cache is the best for your specific situation—or whether you should first optimize other aspects of your application Cache lifetime is also an important factor to consider, because some documents are updated more often than others, and some are not updated at all Unless you have special requirements, files are the best containers for your cache, given that shared memory is not as fast as one would assume and takes up one of your most valuable system resources It's always a good idea to establish your caching parameters through a central facility (be it an include script or a series of defines) so that you can change it in the future—e.g.: going from file to database if you move your site from a single machine to a server farm in order February 2004 ● PHP Architect ● www.phparch.com to respond to growing demand Bibliography • Bergmann, Sebastian, "Caching PHP Programs with PEAR", O'Reilly ONLAMP.com, 2001-10-11, http://www.onlamp.com/pub/a/php/2001/10/11/ pearcache.html • Fielding, et al, "RFC 2616 - Hypertext Transfer Protocol - HTTP/1.1", IEFT Network Working Group, June 1999, http://www.ietf.org/rfc/rfc2616.txt • Ragget, et al, "W3C HTML 4.01 Specification", section 7.4.4, 1999-1224, http://www.w3.org/TR/html4/struct/global.html# h-7.4.4 About the Author ?> Bruno Pedro is a systems engineer with ten years' experience in database-related applications Since 1995 he has been developing web applications He can be contacted at bpedro@ptm.pt To Discuss this article: http://forums.phparch.com/128 57 P R O D U C T R E V I E W 2003 Quebec PHP Conference DVD by Marco Tabini T he 2003 Quebec Conference, organized by PHP Quebec and held in Montreal last spring, was an interesting event from many points of view It was the first conference that I attended as the publisher of php|a—which gave me an opportunity to introduce our magazine to the general public, as well as learn just how much hell one has to go through to get a banner printed in a decent way—and the first PHP event held in Canada at that time From a purely content-related perspective, there was no doubt that the conference was going to be interesting, given that pretty much all the "usual suspects," from Rasmus Lerdorf to Zeev Suraski, were there to speak From an organizational point of view, I was afraid that, given that this was the first conference Figure February 2004 ● PHP Architect ● www.phparch.com organized by the PHP Quebec folks, there would be logistical problems of all sorts Luckily, I was dead wrong—all the speakers (yours truly included) were housed in a very nice hotel in downtown Montreal that, if it weren't for the extremely poor directions provided by a certain travel-related website that shall remain unnamed (and that also sent us somewhere in the middle of Pennsylvania a month later as we were trying to make our way to New York City for PHP-Con), would be very easy to locate for anyone Also, the conference took place in the campus of one of the local universities, which gave it a much more informal atmosphere than your average antiseptic hotel meeting room (it provided all the participants with access to extremely cheap food and round-the-clock Internet access as well) When I recently received my copy of the official DVD collection of the conference, the unfortunate confluence of several facts conspired to keep it, still sealed in its plastic wrapping, on my desk for several weeks—but only until now I must, first of all, point out that the DVD became available many months after the Montreal event, and that, in my opinion, is one of its major drawbacks, for reasons that I'll explain later on The package looks entirely professional and contains two DVDs (for a total of over six hours of content), plus a CD with additional sessions that couldn't fit on the DVDs, as well as a mountain of software of all kinds The DVDs are region-free (meaning that you can play them on any DVD player regardless of which part of the world you're in), but are encoded using the NTSC stan- 58 PRODUCT REVIEW dard, which may cause some problem with older television sets in European countries that support the PAL standard However, if you play the DVDs on your computer, you shouldn't have any problems Given that the conference was held in Quebec—a region of Canada where the official language is French, as opposed to the majority of the country, which speaks English—the event featured lectures and sessions from both anglophone and francophone speakers This, however, does not mean that anyone who doesn't know both languages will have to give up on half of the DVD's contents, as subtitles are provided in both languages This is also a boon if you have trouble understanding either language in its spoken form, but have no problem following one of them in writing Figure ● A Look at the DVDs Let me first say that a major mistake was made when building the DVDs: my session is not on either one of them! All joking aside, the two DVDs contain a grand total of nine sessions, including one by Rasmus Lerdorf—his well-known Advanced PHP talk—and another one by Zeev Suraski, in which he introduces PHP5 and its new features Additionally, you'll find Ilia Alshanetsky speaking about writing efficient PHP scripts, Zak Greant on protecting sensitive data, and many others The quality of the recordings is not Hollywood-style, but provides a very good picture and absolutely crystalclear audio (which is, after all, the important part) My only gripe with the setup is that the camera is fixed on the speakers, which makes it impossible to actually view the screen behind them and, therefore, the slides that they are referencing in their talks Luckily, all the presentations are also included in the CD-ROM in either Powerpoint or HTML format, so that reading along is possible, but not very easy My DVD player, as well as my computer, had no problem playing the DVDs, which points to professional mastering and pressing The menu system, available both in English and in French, is both very easy to follow and fun to use (all the menu items contain some sort of PHP reference) The CD Upon opening the CD-ROM, one has to wonder just how they managed to fit all that stuff in there As mentioned above, it contains all the slides for every session presented at the conference, as well as QuickTime recordings of two additional sessions that are not available on the DVDs (including mine, just in case you were wondering) In addition, the CD contains a mountain of free software, starting from PHP itself (the CD goes as far as version 4.3.3), all the way to all sorts of PHP software, such as e-commerce frameworks, Wikis, servers, and so forth While one could easily question the value of storing free software on a CD (with the risk of it being obsolete by the time the CD will be available to the public), I think it was an excellent idea, because chances are that anyone won't have heard about at least one of the products on it If one discovers some new application he didn't know about Figure February 2004 2003 Quebec PHP Conference DVD PHP Architect ● www.phparch.com 59 PRODUCT REVIEW and then uses it in a future project the CD has, in my opinion, more than paid for itself Pricing and Other Features At $90 US, the DVD is not comparable in price to the average DVD that you pick up from your local electronics store However, it is also not intended for the same audience, of course Based on my personal experience, selling any mass-produced item to a niche market (like software developers, regardless of whether or not they use PHP) is generally very difficult and expensive, because it's impossible to reach the distributions levels that make cheap production possible A Hollywood flick that sells 10,000 copies is a disaster, while a technical DVD like this one that sells the same number of copies would be a major miracle Figure Figure 2003 Quebec PHP Conference DVD Therefore, as you can imagine, the relatively high price tag doesn't disturb me even if you don't factor in the sheer amount of content that the Quebec Conference package gives you—something like six hours (eight if you consider the talks that are stored on the CD) of some of the best PHP minds talking about everything from the basics to advanced topics, and a huge amount of free software for every season Watching this DVD could be almost as good as attending a conference (minus the ability to exchange information directly with your peers), and ninety dollars is an excellent price for that—even if the conference is in your home town All this brings me to a final thought In order to appreciate the real value of this product, in my opinion, you need to microwave a whole vat of popcorn, sit down together with your entire team and watch each session with attention In this optic, the DVDs can be an invaluable learning tool that you can share and reuse over and over again without having to spend lavishly on sending everyone to a conference Unfortunately, this is also where I think the Quebec Conference DVDs could use a bit more work For one thing, as I mentioned initially, the package came out several months after the conference, with the result that at least some of its contents are outdated (although not as much as one would think, considering how much PHP has changed over the last year) Additionally, the fact that the camera is fixed on the speakers—cutting out the slides projected on the big screen behind them—is a major issue when one tries to follow a session he has never seen Even with these limitations, I invite you to give the DVDs a try They are a very original idea, well worth the price of admission If you don't have the opportunity to attend a conference near you, watching the DVDs may be a great way to learn something new php|a February 2004 ● PHP Architect ● www.phparch.com 60 C O R N E R Security Corner by Chris Shiflett S E C U R I T Y S ecurity is gaining more and more attention among PHP professionals As PHP continues to be a key component of the Web's future, malicious attackers will begin to target weaknesses in PHP applications more frequently, and developers need to be ready I am very pleased to introduce Security Corner, a new monthly column that is focused completely on PHP security Each month, I will discuss an important topic in great detail that can help you improve the security of your PHP applications and defend against various types of attacks These topics will not be vague, general overviews, so if you are looking for an introduction to PHP application security, you will be better served by other sources of information such as the PHP manual's chapter on security (http://www.php.net/manual/security.index.php) This month's topic is session fixation, a method of obtaining a valid session identifier without the need for predicting or capturing one The name for this type of attack originates from a publication by Acros Security entitled "Session Fixation Vulnerability in Web-based Applications," although the method itself predates the publication I will expand on the basic idea of session fixation and demonstrate some methods of prevention, all in a PHP-specific context Session Fixation As you probably already know, Session security is a vast and complex topic One of the fundamental principles of Web application security is to never trust data from the client However, in order to achieve statefulness, the client must identify itself by sending a unique iden- February 2004 ● PHP Architect ● www.phparch.com tifier This fundamental conflict creates significant complexities for developers wanting to build secure, stateful applications In fact, the session mechanism in any Web application is likely to be that application's most vulnerable feature, and session security is one of the most complex topics of Web application security on any platform There are numerous types of session-based attacks Many of these fit into a category called impersonation (session hijacking), where a malicious user attempts to access another user's session by posing as that user At the very least, these types of attacks require that the malicious user obtain a valid session identifier, because this is the minimum amount of information that must be used for identification There are at least three ways that a valid session identifier can be obtained by an attacker: Prediction Capture Fixation Prediction only involves guessing a valid session identifier This guess can range from a wild guess to an educated one, depending upon the sophistication of the attack being used With PHP's native session mechanism, valid session identifiers are extremely difficult to predict, so this is unlikely to be the weakest point in your implementation Capturing a valid session identifier is much more common, and there are numerous types of attacks that use this approach When a cookie is used to store the 61 SECURITY CORNER session identifier, a browser vulnerability might be exploited in order to obtain the session identifier When a URL variable is used, the session identifier is more exposed, and there are many more potential methods of capture For this reason, cookies are generally considered to be more secure than URL variables for session identifier propagation, although user preferences must be honored, and browser vulnerabilities exist in all versions of the most popular browser, Internet Explorer (see http://www.peacefire.org/security/iecookies/ and http://shiflett.org/articles/passport-hacking-revisited for more information) Session fixation is a method that tricks a victim into using a session identifier chosen by the attacker If successful, it represents the simplest method with which a valid session identifier can be obtained A Simple Attack In the simplest case, a session fixation attack can use a link: Click here Or a protocol-level redirect: Other methods include the Refresh header, whether passed as a legitimate HTTP header or by using a meta tag's http-equiv attribute The point is to get the user to visit a remote URL that Listing 1 10 11 12 13 Listing 2 Figure February 2004 ● PHP Architect ● www.phparch.com 62 SECURITY CORNER includes a session identifier of the attacker's choosing This is the first step in a basic attack, and the full-circle attack is illustrated in Figure If successful, the attacker is able to bypass the necessity of capturing or predicting a valid session identifier, and it is subsequently possible to launch additional and more dangerous types of attacks Think you're not vulnerable? Consider the code in Listing Save this code as session.php somewhere where you can test it After you ensure that you have no existing cookies from the same host (clear all cookies if you're not certain), use a URL ending in session.php?PHPSESSID=1234 to visit the page For example, http://host/session.php?PHPSESSID=1234 The script should output on your screen upon your first visit Reload the page a few times, and you should notice the number incrementing each time, indicating the number of previous visits With a different browser, or even an entirely different computer, go through the exact same initial steps Upon visiting the URL for the first time, you will notice that you not see Rather, it recalls your previous session Thus, you have impersonated the previous user Now, if you consider that this all began with a session identifier being passed in the URL, you should see the basic danger that session fixation presents Unlike a typical scenario, PHP did not generate the session identifier There are a few shortcomings to this simplistic type of attack The most important shortcoming is that the target application must use the session identifier passed to it, otherwise this attack will fail If your session mechanism is nothing more than session_start(), your applications are vulnerable, as the previous demonstration illustrates In order to prevent this specific vulnerability, you should always ensure that a new session identifier is used whenever you are starting a session for the first time There are many ways this can be achieved, and one example is given in Listing (this approach, too, has at least one weakness, so wait until you finish this article before deciding on the solution that best fits your needs) If the code in Listing is used to start all sessions, any existing session will always have a session variable named initiated that is already set If this is not the case, the session is new The call to session_regenerate_id() replaces the current session identifier with a new one, although it retains the old session information So, if the attacker coerced a user into using an external link to your application that contains the session identifier, this approach will prevent the attacker from knowing February 2004 ● PHP Architect ● www.phparch.com the new session identifier, unless the session has already been initiated A Sophisticated Attack A more sophisticated session fixation attack is one that first initiates a session on the target site, optionally keeps the session from timing out, and then executes the steps mentioned previously An alternative to the approach used in Listing is to call session_regenerate_id() whenever a user successfully logs in, since this is the moment the session data becomes sensitive for most applications For example, whenever you validate a user's username and password, you might set a session variable that indicates success: $_SESSION['logged_in'] = true; Just prior to setting such a session variable, a call to session_regenerate_id() can help to protect against a session fixation attack: session_regenerate_id(); $_SESSION['logged_in'] = true; In fact, a good approach is to always regenerate the session identifier whenever the user's privilege level changes at all, including situations where the user must re-authenticate due to a timeout By doing this, you can be sure that a session fixation vulnerability is not the weakest aspect of your access control mechanism This approach is more secure than the previous example, because it adds another significant obstacle for an attacker to overcome, and it prevents sophisticated attacks where a valid session is first created and maintained Unfortunately, it still has at least one weakness, although your application design may already prevent it An Advanced Attack In the most advanced type of session fixation attack, the attacker first obtains a valid account on the target application—and this is typically only appealing when the attacker can so anonymously On some PHP applications, the login page is a separate script, such as login.php, and this script may not check the user's state, because it seems safer to assume that the user has not been authenticated On the contrary, this approach can allow an attacker to create a session, log into the application with that session, optionally keep the session from timing out, and use the URL to the 63 SECURITY CORNER login page to launch the attack If the login page accepts the new user's login but fails to regenerate the session identifier (because the privilege level has not changed), a vulnerability exists This scenario may seem unlikely, but a thorough examination of your code with this situation in mind is well worth your time There are two easy ways to prevent this particular issue: Have the login page recognize the user's state Always regenerate the session identifier on the receiving script, regardless of the user's state Until Next Time A good generic recommendation for preventing session fixation attacks is to regenerate the session identifier anytime the user provides authentication information of any kind Be wary of passing along such a simplistic catch-all suggestion, however, because misinterpretations are likely when someone is unfamiliar with the type of attack being prevented There is no substitute for a good understanding of session fixation, and it is possible that the best prevention for your applications is not even mentioned in this article Hopefully, you can now eliminate session fixation from your list of serious security risks with which to be concerned If you develop a particularly creative method of prevention, I would love to hear it Until next month, be safe About the Author ?> Chris Shiflett is a frequent contributor to the PHP community and one of the leading security experts in the field His solutions to security problems are often used as points of reference, and these solutions are showcased in his talks at conferences such as ApacheCon and the O'Reilly Open Source Convention, his answers to questions on mailing lists such as PHP-General and NYPHP-Talk, and his articles in publications such as PHP Magazine and php|architect Security Corner, his new monthly column for php|architect, is the industry's first and foremost PHP security column Chris is the author of the HTTP Developer's Handbook, published by Sams Publishing, and is currently writing PHP Security to be published by O'Reilly and Associates In order to help bolster the strength of the PHP community, he is also leading an effort to create a PHP community site at PHPCommunity.org You can contact him at shiflett@php.net or visit his Web site at http://shiflett.org/ 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!* - Strong support team - Focused on developer needs - Full Managed Backup Services Included Our support team consists of knowledgable and experienced professionals who understand the requirements of installing and supporting PHP based applications Please visit http://www.favorhosting.com/phpa/ call 1-866-4FAVOR1 now for information February 2004 ● PHP Architect ● www.phparch.com 64 T I P S & T R I C K S Tips & Tricks By John W Holmes Using FULLTEXT Searches to Prevent Duplicates Depending upon the purpose of your website, you may have to deal with the issue of duplicates Duplicate news posts, forum posts, articles, reviews, or even malicious users quickly posting spam wherever they can You may be able to make use of a FULLTEXT search on the user’s data before it’s put in the database to either catch or flag duplicates, though The premise is that a FULLTEXT search of the complete data from the user on your entire table of content will catch submissions that are exactly the same or even similar Catching the same exact data is easy, as a simple comparison will work, but to really make this worthwhile, we want to catch data that is similar That’s where the FULLTEXT search comes in handy I’m going to talk about and show examples for how to handle this with MySQL, but other database systems should have a similar method to this When running a FULLTEXT search, MySQL will return a relevancy number If more keywords in your data are found within the content of the particular row, MySQL will assign it a higher relevancy number This relevancy is the key to catching duplicates that are similar, but not exactly the same So even though two news items on the latest accomplishments of “Spirit on Mars” are not exactly the same, they’ll contain enough key words about the most recent event to trigger a high enough relevancy that you can catch or flag This relevancy “threshold” is something that would need to be tweaked depending upon your specific application, though It will require you to a little testing with some sample data from your application I did some tests when the current news from Slashdot (www.slashdot.org) for example, and determined that a relevancy number of 30 was adequate This would allow for news items of the same general topic (Linux, SCO, Mars, etc) to be posted, yet flag news items that were very similar, i.e a sentence removed or reworded, yet the same general news Listing shows some simple code that you can use to get you started on this Add your articles, news, etc, and continue adjusting the relevancy threshold until you reach a point where duplicates are caught, but same topic items are not “If you’re using the PASSWORD() function in your applications to control your own user system, you shouldn’t be.” February 2004 ● PHP Architect ● www.phparch.com REQUIREMENTS Code: http://code.phparch.com/20/5 Code Directory: tips-and-tricks 65 TIPS & TRICKS Again, the uses for this are really dependent upon your application Some forums will use a method similar like this to find FULLTEXT matches against the subject of your new threads and provide a list of possibly “related” threads Running a match against users last posts and flagging those users that have a high relevancy may catch those who are spamming forums with the same or similar posts (like those web hosting companies) News sites with multiple people managing submissions may be able to reduce duplicate stories making it to the web site If you come up with a using a method like this, let me know and we may feature your implementation of this idea in a future issue Using the MySQL PASSWORD() Function… Don’t If you’re using the PASSWORD() function in your applications to control your own user system, you shouldn’t be For one thing, and the main news of this tip, is that MySQL 4.1 is changing how the hashing function works so it will product a 41 character hash instead of the 16 that is uses now So the CHAR(16) columns that Listing 1 35 36 Article: 37 38 39 Rel Threshold: February 2004 ● PHP Architect ● www.phparch.com are being used now will not be long enough MySQL 4.1.1 is going to change the hash yet again to produce a 45 character hash This should be transparent to the users, though, as these functions should only be used by the MySQL authentication system and not used within your own applications: Quote: "An upgrade to MySQL 4.1 can cause a compatibility issue for applications that use PASSWORD() to generate passwords for their own purposes (Applications really should not this, because PASSWORD() should be used only to manage passwords for MySQL accounts But some applications use PASSWORD() for their own purposes anyway.)" (http://www.mysql.com/doc/en/Password_hashing.html) The other thing to take from this is that pre-4.1 clients will not be able to connect to 4.1 servers This means that all of the various GUI programs for interfacing with MySQL will need to be updated with the new client This shouldn't be a big deal for those still under active development, but those unsupported yet still popular programs may finally have to be dropped entirely Print or Echo? Most people think that Print and Echo are, essentially, two interchangeable PHP keywords For most practical purposes, that's true enough-they will both send a string to the script's output However, they are not exactly the same Echo is a language construct, which is transformed directly into a special set of commands by the parser built into the PHP interpreter It features a special syntax (for example, it requires no parentheses) and cannot be used as part of an expression Print, on the other hand, behaves like a function whose return value is always int(1) Therefore, you could, in theory, use Print as part of an expression, although for all practical purposes that's pretty pointless No Dumping While we're on the subject of printing information, let's talk about var_dump() This function is often used as a quick-and-dirty method for debugging scripts You know the drill-get to a problematic spot in your code, and dump one or more variables to the screen When you're working on a website, the problem with this technique is that the output of var_dump() contains no HTML formatting and is, therefore, difficult to read in a browser In particular, if you're outputting a very large array that contains many nested elements, everything will be displayed on the same line and create a confusing mess The simplest way of making the output readable (short of writing your own version of var_dump() or using the PEAR::Var_dump package) is to output a 66 TIPS & TRICKS tag before your actual output: echo ""; var_dump ($my_var); However, you now need to write two lines of code whenever you want to dump something to the browser, and if you have to a lot of mucking around to find where your problem is, this approach can become very time-consuming Luckily, var_dump() actually supports a variable number of parameters-you can actually dump more than one variable with a simple call Therefore, all you really need to is change your code ever so slightly to include the tag in your call to var_dump(): other database systems with PHP Let's see some PostgreSQL, Firebird, Oracle and even MSSQL tips on here If you're using one of these databases, you're not alone Share the tricks that make your life easier with the rest of us! Also, those of you not already playing with PHP5 should be Those of you that already are, send in your tips and tricks for converting common bits of code from PHP4 to PHP5 These are the kind of tips people are going to be looking for in the coming months when, hopefully, PHP5 comes out officially var_dump ('', $my_var); You can even add a closing tag at the end if you want to leave the remainder of the script's output undisturbed Let's Talk About Other Databases and PHP5 Most tips here and there deal with PHP interacting with MySQL, but there are hosts of other databases out there that seamlessly interact with PHP I write about what I use, but I encourage any of the readers out there to send in your tips, tricks, and knowledge about using Have you had your PHP today? About the Author ?> John Holmes is a Captain in the U.S Army and a freelance PHP and MySQL programmer He has been programming in PHP for over years and loves every minute of it He is currently serving at Ft Gordon, Georgia as a Company Commander with his wife and two sons http://www.phparch.com NEW COMBO NOW AVAILABLE: PDF + PRINT The Magazine For PHP Professionals February 2004 ● PHP Architect ● www.phparch.com 67 Why Can’t We All Just Get Along? e x i t ( ) ; By Marco Tabini S ometimes during the month of February, I happen to celebrate my birthday For some people, birthdays are a cause for happiness and, if you're young enough, for lots and lots of beautiful gifts Being past the beautiful gift stage myself, however, the cause for happiness is long gone Even though I am not old (and wouldn't admit to being old even if I were old, which, in case you missed it, I most definitely am not), another birthday means that yet another year has gone by without me finally overtaking Bill Gates as the world's nerdiest man Finding myself in the month of February, therefore, is the equivalent of stepping into a puddle of chocolate ice cream only to find out that it wasn't ice cream after all, and someone forgot all about the "scoop the poop" rule at the local park Along with me being one step closer to Programmer Heaven (that mystical place where there are no computers whatsoever and the most advanced form of technology is the "light switch"), everything else is also one year older—including PHP Granted, it might be slightly self-centered to measure the advancing age February 2004 ● PHP Architect ● of PHP in correspondence of the advancing age of yours truly, but it helps me put things into perspective Where was PHP a year ago? Well, I'm tempted to say that it was pretty much in the same state as it is today, but that would be a gross oversimplification Leaving PHP5 aside for a moment, PHP4, the "stable" PHP platform, has not changed dramatically since then, although some of the new features that have become available have made a bit of an impact The introduction of file_get_contents(), for example, ended once and for all the need to write those ultra-hated three lines of code where just one is more than enough What has really changed in the last year is the level of familiarity and confidence that people have with PHP I see it, in particular, in the complexity of the articles that reach our office these days When we started out, our goal was to delve into the lesser-known and more advanced capabilities of PHP, and that we did The articles that we receive today, however, sometimes surpass even my wildest dreams This month, for example, we feature an article on www.phparch.com writing an SMS gateway using nothing more than PHP, an open-source package and a common Nokia cell phone It almost sounds like something taken out of a MacGyver episode—I'm sure the Swiss Army Man himself would approve Surely, a messaging solution is not everyone's bag but, to be able to consider developing an application like that, one has to be very confident in the capabilities of the platform he chooses—and that we are, because PHP has shown that it is here to stay, and that it has the ability to deliver and to deliver consistently Unfortunately, our ever increasing confidence in PHP4 is going to make adopting PHP5 much more difficult For better or worse, intimate knowledge of a development platform means learning to cope with its deficiencies, and sometimes to take advantage of them in a way that its original designers never anticipated The history of computer programming is full of cases where this tenet holds true; for example, for those of you old (and crazy) enough to remember, some enthusiasts learned that the feature that made it possible to change the border colour of the Apple IIGS' screen could be used to write text and draw animations outside of the actual addressable area of the screen, and thus created some of the most memorable demos seen until that day (sadly, the GS died an awful death shortly thereafter, so that the computer I bought with six months worth of savings is now safely stowed away from my wife's Spring Cleaning reach) On a more mundane level, a bug in the on-chip microcode for the original Intel 8088 CPU was once used by the IBM/PC bios to determine whether a computer was equipped with the older 8088 or the newer 8086 When the 286 and later x86 models came out, a different feature of the processor, originally intended for other uses, was taken advantage of for the purpose of identification, until Intel finally caught on and started to provide a CPUID command as part of the Pentium's machine language 68 EXIT(0); Why Can’t We All Just Get Along? instruction set The underlying characteristic of all these examples is that they made use of features that the original designers of their platforms had not anticipated Given that we've had a few years to get intimately acquainted with it, it's more than likely that something similar has happened with PHP4 and all sorts of things will start breaking once PHP5 is officially introduced I know at least some of my code will— taking shortcuts (also known as "ugly hacks") with OOP in PHP4 is all but inevitable-and I won't be too happy about it How does one go about addressing a problem like this? Well, I envision one of three possible solutions: • PHP5 features a "PHP4Compatibility" mode The likelihood of something like this happening is pretty much on the same level as Canada winning the Soccer World Cup (for those who don't follow soccer, let me be a bit less cryptic—it's not going to happen) Even if it were technically feasible, it would be a pretty dumb solution to the problem— I can only begin to fathom the disastrous consequences of trying to simulate PHP4's erroneous handling of OOP in PHP5 • The "you pays your moneys and you takes your chances" approach—no facility is created to allow for the peaceful coexistence of PHP4 and PHP5 code in the same project (or on the same server) In my opinion, this would also be a pretty bad move, given that most people can't afford to run two servers just to be able to use both platforms, and no-one wants to rewrite entire applications unless they really have to February 2004 ● PHP Architect ● • PHP4 and PHP5 are made to work well together Being able to run both PHP4 and PHP5 code on the same server would be as excellent an outcome as one could possibly hope, so that new code can run alongside old one Let's take a closer look at this last possibility The best possible scenario would be to be able to run both PHP4 and PHP5 scripts on the same server and let them be capable to share everything, from cookies to session information On some level, this may be feasible, but I think that, more realistically, one should aim lower and simply hope to be able to run PHP4 and PHP5 projects on the same server With this approach, if, say, MySQLAdmin or Gallery don't work with PHP5, you can still use them together with your other PHP5-compatible websites without breaking the bank In order for this to happen, I think that at least two events must take place First, the PHP Team must ensure that such coexistence is possible, and that crystal clear instructions be provided for everybody who wants to take advantage of it In particular, the instructions should be easy to implement for hosting companies: considering the level of competitiveness and the low profit margins they are used to working with, a simpler solution will mean that more providers will be able to take advantage of it, resulting in cheaper and more stable hosting for everyone Another important step in the direction of better coexistence between different versions of PHP is in the naming convention for PHP files Right now, we're all used to ending our files in php However, when PHP5 comes along, if we want to be able to use both PHP4 and PHP5 on the same server, we'll have to find another solution, since most web servers determine a file's type by its extension If you're planning to write PHP5-only software, it might be worth to think about using some- www.phparch.com thing different, such as php5, for example This is not a new idea—it's already commonly done with PHP3 code (which ends in php3); I just think that it should be done as a matter of routine for every version of the language The final nail in the coffin of PHP4 will be proper user education As of this writing, documentation for PHP5 is still rather sparse, and it will probably take a while before that changes in a meaningful way It's important to understand that by "documentation" I don't mean the run-of-the-mill references—be it online or in print-that tell you how the new OOP functionality or the new extensions work I'm referring to those resource that tell you how the new features of the language can be used There is a major difference between explaining what an exception is and showing to someone that in practical terms it can be used to cut down and simplify error checking to a minimum without any appreciable loss of functionality, just like there is a difference between showing you how to access a database and using that functionality to build an SMS gateway The problem with making these "advanced" techniques available to the general public is that there has to be someone capable of understanding them and putting them to practical use first, and this is more likely to happen with a mature and well-understood language like PHP4 than with a new-and in some cases dramatically improved—platform like PHP5 One has to start somewhere, however, and hopefully we'll see more and more PHP5 tutorials on the web As always, we'll try to bring you a good balance—introducing new features that are waiting for you in PHP5, but keeping a watchful eye on the fact that, on a day-to-day basis, we are all still more likely to use PHP4 for quite a while php|a 69 ... \_/usr/local/bin /php -q /smsparse/smsparse .php php: /usr/local/bin /php /usr/local/lib /php /usr/local/lib /php. ini This means that I have the PHP interpreter''s binary installed in /usr/local/bin /php It''s... Figure February 2004 ● PHP Architect ● www.phparch.com 44 FEATURE Profiling PHP Applications Figure Figure February 2004 ● PHP Architect ● www.phparch.com 45 FEATURE Profiling PHP Applications execution... my MySQL tool of choice php| a Figure February 2004 ● PHP Architect ● www.phparch.com 40 Profiling PHP Applications F E A T U R E by George Schlossnagle I f you program PHP professionally, there