PROGRAMMING PHP 5

The Next Generation Onward and upward Of all the programming languages to have emerged in recent years, PHP is one of the great success stories. It has fostered a loyal community of devel- opers and, despite some well documented issues, still maintains its popularity. BY STEVEN GOODWIN www.space -center- bremen.de

oes its latest incarnation, PHP 5, find the original documentation lurking PHP community was also growing by do justice to its heritage, or is it at [1]. leaps and bounds: a number of third Ddestined to become a skeleton in PHP as we know it really began with party databases were now supported, the the closet? Steven Goodwin finds out. version 3, released in June 1998. Unlike PEAR repository came into being, and the upgrade status to PHP/FI 2.0, PHP 3 the documentation had grown into a You’re History was a complete rewrite by Rasmus, comprehensive, and very usable, online The first version of PHP was written in along with Andi Gutmans and Zeev manual [2], currently available in 26 dif- 1994 by Rasmus Lerdorf and constituted Suraski. From a technical standpoint, it ferent languages. a number of scripts for building web was very much improved, and more PHP5 is claimed to be the latest and pages. The term PHP/FI was coined in capable of dealing with high volume web best version of PHP, utilizing another 1995, and was followed by PHP/FI 2.0 in sites and e-commerce applications. It new code engine (Zend 2), an impressive 1997, with PHP/FI standing for Personal also featured the first signs of object ori- new object model and a host of new fea- Home Page / Forms Interpreter. Even entation (see Box: Uh Oh!), and a though some of the functionality that we change of acronym to the still-in-use, Uh Oh! know today was present in these early PHP: Hypertext Preprocessor. Object Orientation is more a paradigm than versions, beyond a small cult group of Version 4 was essentially an extension it is any particular type of programming. developers, it was largely unheard of. of 3, using the same syntax and seman- When used correctly,its benefits include Curious readers and history students can tics. It featured output buffering, code re-use,abstraction of detail,data improved object orientation, and various encapsulation and polymorphism.The When builders go down new features (like references) and implementation of an OO solution involves the pub they talk about instructions, such as the foreach control objects,a much over-used term that (in this football. Presumably structure. Behind the scenes too, a lot instance) indicates that both the data,and therefore,when foot- HOR had changed, as the PHP code base had the code that manipulates it,are bound T ballers go down the together in one unit. Each object is often pub they talk about been modularized and optimized, with represented by a class.The data held within builders! When Steven Goodwin goes some code running over 200 times faster. this class represents its current state,and down the pub he doesn’t talk about This was largely thanks to a new THE AU football. Or builders. He talks about the code that affects it are called methods, computers. Constantly… engine, known as Zend, which was a or member functions. complete re-write of the original. The

64 July 2004 www.linux-magazine.com PHP 5 PROGRAMMING

tures. It has gone through four beta ver- vice to the backwards compatibility capitalized) are used for the extensions sions with, at the time of writing, the issue. The core language looks no differ- like SQLite and SOAP. current version standing at Release Can- ent to that of PHP 4 and although there There are a slew of new functions in didate 2, made available on the 25th have been a few backwards incompati- PHP 5, all detailed in [6]. Most of them April 2004. It is claimed stable, but “still ble changes, these have been in the provide better support for the core lan- not recommended for mission-critical name of stricter standards, and are guage, although most have been use”. True stability will come with time, detailed in [5]. available before in libraries, or as user- although the experiments of this author If your code is polite and follows the added comments in the standard have shown it perfectly usable for small described function behavior to the letter, documentation on the main PHP site [2]. to medium scale work. most of these changes won’t affect you, These functions break down into five but be warned as array_merge now only basic groups. See Table 1. Little Fluffy Clouds accepts arrays. This may cause E_WARN- Before we launch into specific details The source code for PHP 5 can be down- INGs to appear without apparent reason. of some of these features, there are two loaded from [3] as a five MByte tarred It is worthwhile to note that illegal string development functions to highlight. The gzip file, although the only official bina- offsets are now considered errors (not first is var_dump which has an improved ries available are for Windows. Brave warnings). Note also that, look, and expands the information inside Debian users can grab the .debs from [4] the class, as does print_r. by adding the line, $app.is_object() // Example of var_dump deb http://packagesU returns an object and one needs to use object(MyName)#5 (2) { .dotdeb.org ./ the modern form, ["firstName"]=> string(6) "Steven" to their /etc/apt/sources.list, although is_object($app) ["lastName"]=> this will not be guaranteed to work. string(7) "Goodwin" Assuming you’re compiling from source to get a boolean value. However, most } the traditional trio is employed thus, practical code will not (or should not!) have these errors present. For the termi- The second is a new function called $ ./configure --with-mysql U nally paranoid there is a compatibility debug_backtrace, which returns an array --with-apxs mode. This can be used to determine showing the call stack. This has been $ make whether the bug is in your code, or the partially back ported into PHP 4, but # make install new PHP 5 interpreter. It can be con- looks to be a stalwart for all PHP devel- trolled with the line, opers looking for quick, light weight, The options for ./configure may need to debugging assistant, without resorting to be adapted, depending on whether you zend.ze1_compatibility_modeU xdebug. have (or want) MySQL support. The pri- =Off mary dependency essential for PHP 5 is a The Invisible Man recent version of libxml2 (version 2.5.10 in your php.ini file. Two sample ini files Among the list of core language features or above), but once that’s available, a come with PHP 5, a development version there’s a small selection that has been basic compile and install can be accom- and a more secure release version. devoted to code that doesn’t exist! That plished with a fairly minimal time outlay. Although neither sees the need to use is, if a non-existent class method is called, Documentation is included in the pack- the compatibility mode. the special __call function is invoked. age, which also details how to run PHP 4 Developers working on the bleeding and 5 alongside each other. If you’re edge will also have realized that studly- class Reverse { compiling PHP 5 as an Apache module, Caps (first word in lower case, and the function __call($function, U then the traditional rules for building initial letter of every other word being $arguments) DSO’s (Dynamic Shared { Object) apply. Table 1: New function groups return strrev($function); } Area Number Notes A Grand Don’t Come } Arrays 6 Mostly to determine differences between For Free arrays The first, most obvious, ques- InterBase 19 Various functions for Interbase users $r = new Reverse; tion with such a new system iconv 7 Handles internationalization features,and print $r->this_doesnt_exist(); is a consideration of old code. MIME headers Does it break anything? Is Streams 8 Most supplying useful low level socket Or, if you try to access a member vari- this a backwards step? Fortu- handling functionality able that doesn’t exist, one of two nately, the answer appears to Misc 34 General purpose functions,including PHP different functions will be called, syntax checker,string conversion and process be no. Most of the changes in control depending on whether you tried to read this release have paid lip ser- from, or write to, the variable.

www.linux-magazine.com July 2004 65 PROGRAMMING PHP 5

01 class Length the appropriate class files at the start, ples, which makes it easier for PHP 5 02 { compared to sporadic on-demand load- developers to interact with them. 03 function __get($variable_U ing (which may include disk seek times) There are two main areas of object ori- name) throughout the script’s lifetime. ented study in PHP 5. The first are the 04 { Be careful when using __autoload changed features. These are cases where 05 return strlen($variable_U since file names are case-sensitive, but improvements have been made to the name); PHP class names are not. This could language that allow traditional OO 06 } cause missing classes to try and load design patterns to be used natively 07 non-existent files from disk. Porting code within PHP. These were possible previ- 08 function __set($variable_U from a Windows environment will often ously, albeit with some minor code name, $value) include at least one of this variety! hacks. The second involves new features 09 { that haven’t been technically possible 10 print "I can't set the U The Girl in the Other Room before, because of the language design. length of $variable_name U Of all the new features in PHP 5, one cat- Let us cover the improvements first. to $value!"; egory stands proud: object orientation. The biggest improvement is the way 11 } OO features have been part of PHP since references and object copying occur. 12 } version 3, although they have always Previously, the object model was to 13 been rather minimal in scope. PHP has always copy objects as they were passed 14 $len = new Length; into, and out of, func- 15 $len->thisname = 10; Table 2: Member Access tions. This made it 16 print $len->thisname; Type Accessible to own class …to derived classes ..to the world difficult to handle Public Yes Yes Yes objects efficiently, and All three of these functions only work as so references were Protected Yes Yes No class methods, so you can not have a added. Any PHP code Private Yes No No global __set function to cope with every with extensive object non-handled case. use would therefore be On the surface, these might appear as never been an OO language, merely a full of the & symbol, and omissions quirky functions, but of little use. How- language that happens to support some could lead to hard-to-spot bugs. ever, they do have a number of serious object oriented features – namely classes. applications. The __call function, for However, PHP’s previous support for 01 class MyName { example, could be used to create mock OO had very limited encapsulation and 02 var $name; objects, while __set and __get can pass data hiding capabilities, making it 03 } information to and from a database, unsuitable for large projects without 04 while remaining completely transparent requiring a great deal of care. PHP 5 adds 05 function ChangeNameU to the end user. such a wealth of OO functionality that in (&$newname) Another feature of this ilk is one fell swoop it sits close to OO-Perl 06 { __autoload, which gets called whenever and Ruby. As a paradigm, OO is well 07 $newname->name = "Steev"; a non-existent class is instantiated. The understood and (despite the bad press 08 } classic example for this feature is to load attributed it, thanks to the nuances – and 09 class files on demand. For example, nuisances – of C++) is quite suitable 10 $me = new MyName; for large scale operations. Many toolkits, 11 ChangeName($me); function __autoload($classname) such as GTK, are based on OO princi- 12 print $me->name; { require_once "$classname.inc"; Listing 1: London pubs } 01 // sample file in boxout: London pubs 02 $pub_list = simplexml_load_file('londonpubs.xml'); $me = new UnknownName; 03 // Causes UnknownName.inc to U 04 // iterate through each 'pub' element be loaded before class creation 05 foreach ($pub_list as $pub) { 06 if ($pub->name == $rate_this_pub) { // check name element This allows the script to start and run 07 $pub->name['rating'] = $rating_for_pub; // write a rating very quickly, only loading additional attribute class resources when it needs to, allow- 08 print "Rating changed for $pub->name, to $rating_for_pub"; ing larger class hierarchies to be 09 } employed without degraded the per- 10 } formance in simpler cases. High 11 performance environments must be 12 $new_xml_data = $pub_list->asXML(); careful to consider the load time for all 13 file_put_contents("newlondonpubs.xml", $new_xml_data);

66 July 2004 www.linux-magazine.com PHP 5 PROGRAMMING

This simple example, to print the name function) with the word private, and this Cornflake Girl ‘Steev’, would fail to work if the & was will be enforced. Another important change has been with omitted in line 5, as a brand new copy of the constructors. Instead of creating a the MyName class would have been cre- 01 class MyName { function with an identical name to the ated and assigned to $newname. The 02 private $name; class, name ‘Steev’ would then have been 03 } assigned to this new copy, and not the 04 class MyName { object passed in from line 11. 05 $me = new MyName; function Myname() With PHP 5, class objects are passed 06 print $me->name; { as a reference by default, not value, so // This is the constructor,U the & symbol is no longer needed, mak- Which produces the error, called whenever a new U ing it less error prone. The reference MyName is created! syntax is still maintained for compatibil- Fatal error: Cannot access U } ity. private property MyName::$name U } in somefile.php on line 6 05 function ChangeName($newname) a constructor can now be created by Even derived classes will not be able to using the new name __construct. At a The use of this new syntax is encour- use $this->name to access the variable. first casual glance, this appears, on the aged, and should lead to the older Any attempt to do so will cause PHP to surface, to only be a minor change, how- explicit references being deprecated in create another public variable that be- ever it becomes a major time saver if you future versions. longs to the derived class. This can cause need to change the class hierarchy, since The only problem with this feature is subtle errors, but private members and calling the parent class’s constructor that the code appears to be run-time methods are easy enough to learn, and now becomes, compatible with versions 3 and 4 – but can add great security to your code, es- isn’t! In the rare cases when your older pecially when you’re developing class MyFullName extends U code relied of the copying of objects, you modules. MyName { will now need to clone them instead. Protected is a further extension of pri- function __construct() This is a new feature, made necessary vate. Any member that is protected can { because of the new object model. Calling be accessed by the class itself (just like parent::__construct(); the __clone function will make a bitwise private), but it can also be used by any } copy of the existing object, as will the derived class, such as MyFullName: } more traditional, class MyFullName extendsU In large formal systems, the class hierar- $new_object = clone $old_object; MyName { ... chy should not be changed often (if at all) as this can break the design. How- Furthermore, any class that overloads See Table 2, on the previous page, for a ever in smaller ad-hoc systems this can the __clone function can dictate how it quick breakdown of these security defin- prevent bugs from creeping in when new should be copied, for cases where refer- itions. classes are added in between a parent ence counting is required, or where the In addition, there is a new keyword and its child. standard copy is not good enough. called final which can be added to a There only appears to be one primary member function to prevent it from limitation with constructors and even Guns Of Brixton being derived or extended any further. that limitation is fairly inconsequential Probably the most visible addition to All member variables, and methods, in practice. That is, you can not overload PHP’s OO handling code is represented are created as public by default. This the constructor as you can in other by three new keywords: public, private ensures backwards compatibility, and Object Orientated languages. This limits and protected. Under PHP 4, every mem- only functions called public, private or the number of ways you can create the ber variable of a class could be read by protected are likely to have problems. object: anyone. From any code. Placed any- where. London Pubs Such variables are termed public, in A sample XML file used in the example might appear thus: much the same way as permissions in the Linux filesystem. By convention, any All Bar One

26-30 London Bridge U variable prefixed with an underscore was Street, London, SE1 2SZ
considered private and should only be The Banana Store
1 Cathedral Street,U accessed by the class itself. However, London, SE1 9DE
this is only a convention, and before The Barrowboy and Banker
6-8, U PHP 5 could not be guaranteed. Now it is Borough High Street, London, SE1 9QQ
possible to prefix a member variable (or

www.linux-magazine.com July 2004 67 PROGRAMMING PHP 5

//Not directly available in PHP5 (such as database locks or file handles) 08 $me = new MyName("Steev"); may not. Such functions are declared 09 $this->local =& $single_U $full_me = new MyName("Steven",U using the name __destruct. var; "Goodwin"); Backwards compatibility is still an 10 } issue in OO, and fortunately, there are 11 } If you need this functionality, I suggest precious few cases that could fail. How- using default parameters in the construc- ever, any member function called So, if you wanted to know how many tor and patching the data accordingly. __construct or __destruct will cause the MyName classes had been created, in code to behave in an undetermined man- PHP 5 you could write: function __construct($name1="",U ner (especially if the function name $name2="") doesn’t reflect its traditional purpose). 01 class MyName { { As will any functions using the other 02 static $class_count = 0; if ($name2 == "") { new keywords. 03 $this->name = $name1; U 04 function MyName() // no surname Stuck On You 05 { } else { Another very welcome improvement is 06 MyName::$class_count++; $this->name = "$name1 $name2"; the ability to use static methods and 07 } } member variables. A static member is 08 } } one that is identical across every 09 instance of the class. Previously, it was 10 $you = new MyName; It is also possible for constructors to be possible to write code that looked like 11 $me = new MyName; made private. This trick prevents other static members were available, but the 12 $them = new MyName; classes from creating specific objects, as popular method of doing so (given 13 $everybody = new MyName; is required when implementing single- below) requires extra memory. 14 tons, as we’ll see shortly. 15 print MyName::$class_count; Destructors are a welcome addition to 01 class PHP4FakeStatic PHP. They are called automatically 02 { Static members do not have a specific whenever an object is destroyed, which 03 var $local; instance of the class, so they must be traditionally occurs when the code has 04 set (and read) without $this, as seen finished executing. Although the mem- 05 function PHP4FakeStatic() in line 6. Similarly, member functions ory that a class uses is always reclaimed 06 { can be called directly using the class automatically, any external resources 07 static $single_var=0; name::function name() syntax. How- ever, be warned that because static PHP 5 Features in Brief members exist outside of any specific Feature Notes instance, it is not possible to access any Object references Removes need for & non-static data from within the class. Constructors and destructors Now have unified name,regardless of class name Any static function that tries to use $this Public/private/protected For data hiding will be greeted with the error, Static members One copy of a variable for all instances of call Final keyword Prevents further derivation of classes Fatal error: Using $this when U Class constants Use const cvar = 3.1415 instead of define not in object context in U Objects copied by __clone function Needed now objects are passed by reference somefile.php on line 6 Type hinting Indicates the required type for a parameter. A nod to a more strongly-typed PHP Instance of It is possible to determine the type of a dynamic object with $foo instanceof This construct can also be used to create SomeClass a singleton, as mentioned above. The Indirect referencing Allows $foo->a->b; in some cases singleton a design pattern whereby only Automagic class loading Use __autoload to bring in appropriate files one instance of a class can ever be cre- Setters and Getters Overload member variable access with __get and __set Runtime method overload __call will be invoked if the original function doesn’t exist ated, and is useful for handling log files Abstract classes and interfaces For more complex OO code and other resources where it doesn’t Exceptions Exceptions can be caught and thrown as per other languages make sense to have two. SimpleXML Supports loading and saving of well formed XML SQLite An available database without running extra services. Not recommended for high 01 class Singleton loads 02 { Filters Flexible text processing,with built in filters for rot13 03 static private $instance U Streams To load data resources from arbitrary locations,using various protocols (e.g. ftp,http). = NULL; Improved socket handling too 04 Namespaces These have been removed! 05 private function U Extensions Various extensions for SOAP,SimpleXML and MySQL. __construct() { }

68 July 2004 www.linux-magazine.com PHP 5 PROGRAMMING

06 text stream with asXML. See Listing 1. At 07 static function get() this point it appears as standard, compli- Problems Despite all the newness present in PHP 5,a 08 { ant, XML. See box: London Pubs. number of older problems still remain.There 09 if (self::$instance U When working with your own XML is still no stack protection,for example,and == NULL) { files, there are few limitations and even most code that attempts to allocate too U 10 self::$instance = new fewer problems. It just works! However, much memory (forced over-allocation) will Singleton(); in more complex applications the limi- still crash. Fortunately,most of these cases 11 } tation of namespaces within XML can can only happen through malicious intent. 12 return self::$instance; be problematic, as SimpleXML ignores There is also a problem when using the 13 } them, acting is if they don’t exist. (deprecated) dl function,whereby an exten- 14 When SimpleXML is not enough and sion loaded twice (one explicitly with dl, 15 function hello() you need more powerful editing features, followed by one implicitly through new) can 16 { don’t worry. There’s no need to port cause a fatal exit as the extension is deleted before the objects created by the library are. 17 print "Hello, U your code over to DOM, since two con- singletons!"; version functions have been provided. 18 } go back to PHP 4. With this in mind, 19 } $sxe = simplexml_import_domU PHP 5 should be considered completely ($dom); separate from PHP 4, and you should not Every member of the singleton class can $dom = dom_import_simplexmlU try to write code compatible with both. only be called through the get function, ($sxe); There may also be some pain during as there is no other way to get a refer- the migration process, as occasional ence to the singleton object. This comes PHP 5 has better support for various problems with old code will arise. Most from the private constructor, which stops XML technologies, such as XSLT and of these should be caught with sufficient any class (other than itself) creating an SOAP, as the library underneath Sim- code auditing. When trialling PHP 5 on object. For example, pleXML (libxml2) is used throughout. my own system for example, there were very few niggles, and my home site print Singleton::get()->hello(); Martha’s Harbour (with around 100 pages) took under an In general, a lot of good work has found hour to get working. Let ItGrow its way into PHP 5. The integration of For those coming to the language PHP 5 features several new, and SQLite will appeal to those wanting to afresh, especially those looking for good improved, extensions. MySQLite is cer- experiment with databases without the OO capabilities, PHP 5 hits the spot in all tainly one of the most talked about, as is hassle of configuring extra daemons, and the right places and appears as an effort- the closely related MySQLi (which is the the Simple XML module will make it so less OO language. It should encourage MySQL improved version, supporting easy to migrate away from flat files that developers who have been weary about amongst other things, prepared state- many people will do so. Both should PHP to return with renewed vigor, and ments and variable bindings). However, raise the standard of available PHP appli- may even convert a few programmers the inclusion of SimpleXML is probably cations. These are just two of the many from other languages. my favorite. While not as feature-full as good modules available with version 5. Only time will tell… ■ DOM, it does provide a very efficient Alas, space does not permit detailed way of handling simple XML, such as explanation of them all, so a brief run INFO data and configuration files. down of all the new features can be [1] PHP/FI Version 2.0: After reading the XML into a Sim- found in the box: PHP 5 Features in http://www.php.net/manual/phpfi2.php pleXML object you can modify the data Brief, and on the web at [7] and [8]. [2] PHP manual: within PHP (using the standard data However, the biggest selling point of http://www.php.net/manual/en/ types), and then save the same object PHP 5 must be the new object model. [3] Latest stable version of PHP: out to disk by serializing it into an XML Almost everything else has been avail- http://www.php.net/downloads.php#5 able before as a third party module, or as [4] Stable Debian repository: library code. Mr. Big http://www.dotdeb.org/ The OO in 5 is very good, and such an The penetration of PHP is quite incredible. [5] Backward Incompatible Changes: improvement on previous versions that For instance,according to SecuritySpace.com http://www.zend.com/manual/ many old hands will have to unlearn PHP is installed on over half of the Apache migration5.incompatible.php servers surveyed in March 2004,and on 33% their various tricks in order to write [6] New PHP 5 functions:http://www.zend. of the 47,173,415 domains queried by Net- effective PHP 5 code. For them, this tran- com/manual/migration5.functions.php craft in the same period. Also,from a study sition will be the hardest part of [7] Changes in PHP 5/Zend Engine 2.0: of all the projects in the SourceForge.net migration. Not the new syntax rules (as http://www.php.net/zend-engine-2.php repository,11.2% (4,433 of them) are written they are simple to learn), but the feeling in PHP,a feat only bettered by C/C++ and of loss as once you start using the new [8] Migrating from PHP 4 to PHP 5:http:// Java. www.zend.com/manual/migration5.php syntax you’ll never want (or be able) to

www.linux-magazine.com July 2004 69