Noticeable Changes between PHP/FI 2.0 and PHP 3.0 ================================================= This file was designed to be viewed with a tab size of 4 characters. This file is divided into 4 sections: 1. Downwards incompatible language changes. This section includes all of the changes in the core language which may require people to modify their scripts before using them with PHP 3.0. It does NOT list changes made in the behavior of specific functions. 2. New language features. This section includes all of the new additions to the core language, that may be used to enhance scripts designed for PHP 3.0. Likewise, it does not include a listing of new functions. 3. Structural changes not directly effecting the end user. The core of PHP 3.0 is a complete rewrite. As such, many issues effecting PHP/FI 2.0 were addressed and vastly improved in this version, resulting in a much more stable and efficient implementation. This section lists these changes in design. 4. Other changes that don't fit in any of the above categories. Please remember that PHP 3.0's core is a complete rewrite, and thus, there may be other undocumented incompatibilities we haven't thought of ourselves. If you think you've found a incompatibility (or a new feature) which is not listed here, please mail us at php-dev@php.iquest.net. - Zeev ------------------------------------------------------------------------------ Downwards incompatible language changes ======================================= [1] The close-PHP tag has changed from > to ?> This means that instead of writing: You should write: PHP3 also includes support for a longer-form start tag that is XML-compliant: The ability to use the short start tag ('5) break; if ($i>5) break 2; } } The first break statement would end the inner loop every time $j is greater than 5. The second break statement would end both the inner and outer loop when $i is greater than 5. Note: For this matter, switch statements are considered as loops. So if you write "break 2;" inside a switch statement, you would be asking to break out of the switch, and the innermost loop in which is nested. [5] Switched to C-style declaration of functions. Here's a pretty useless function which makes a good example: function concat($str1,$str2) { return $str1.$str2; } NOTE: The old style function definition is still supported, to allow easier upgrading from PHP/FI 2.0 scripts. Simply change 'function' to 'old_function' for these functions. [6] OOP support Classes and inheritance are supported to a limited extent in PHP 3.0. Here's how to declare a simple class: class simple_class { var $property1,$property2; var $property3=5; function display() { printf("p1=%d, p2=%d, p3=%d\n", $this->property1, $this->property2, $this->property3); } function init($p1,$p2) { $this->property1 = $p1; $this->property2 = $p2; } }; Here's how to create an object of that class: $obj = new simple_class; At this point, $obj is an object with 2 uninitialized variables, 1 initialized variable, and 2 member functions. No protection is made on the internals of the object, and using its properties is simple: $obj->property1 = 7; would assign 7 to $property1 inside $obj. Calling member functions is also simple: $obj->display() would run the display() member function of $obj. Note that the implementation of display() uses the special variable $this, which is replaced with the object the function is called on. Inheritance is pretty simple too: class complex_class extends simple_class { var $property4="test"; function display() { printf("p1=%d, p2=%d, p3=%d, p4=%d\n", $this->property1, $this->property2, $this->property3, $this->property4); } } Basically, the class complex_class inherits everything from its parent, simple_class, except properties or member functions which override the ones in the parent. In this example, since we supply an alternative display() function, it would be used with complex_class objects instead of the display() function that was declared in simple_class. On the other hand, since we don't supply an alternative init() function, complex_class objects would have the same init() function as simple_class objects do. As with expressions, it's impossible to teach OOP in a few lines, and personally I'm unclear as to how useful this would be in day to day scripting. If you like this, play with this until you figure it out :) Objects can reside in arrays, and can contain arrays. However, a limitation of the current implementation doesn't allow an object to contain an array of objects (actually, this is allowed, but there's no way to address the properties of such an object directly, but only indirectly). For example, assuming $a[3] is an object, $a[3]->b[2] is an object as well, you can't address the properties of $a[3]->b[2] (i.e. you can't write $a[3]->b[2]->foo = "bar", for instance). [7] Function pointers are now supported. A simple illustrative example: $func_ptr = "time"; $current_time = $func_ptr(); is identical to $current_time = time(); [8] Indirect references are much more powerful. For example, one can use the dollar operator an infinite amount of times: $a = "b"; $b = "c"; $c = "d"; $d = "e"; $e = "Testing\n"; echo $$$$$a; Would display $e's content, which is "Testing\n". In addition, one can use complex expressions to generate variable names using a perl-like notation: $i="123"; ${"test".$i} = 5; would assign 5 to $test123. [9] A string concatenation operator was added, '+' no longer concatenates strings. A perl-like string concatenation operator was added, the '.' operator. It converts both of its arguments to strings, and concatenates them. For example: $result = "abcd".5; assigns "abcd5" to result. Note that under PHP 3.0, the '+' operator no longer performs concatenation if its arguments are strings. Use the '.' operator instead. [10] Supports passing function arguments by references instead of by value. Support for passing function arguments by reference instead of by value has been added. This doesn't result in having to change the function implementations in any way, but, when calling the function, you can decide on whether the variable you supply would actually be changed by the function, or a copy of it. Example: function inc($arg) { $arg++; } $i=0; inc($i); # here $i in the outer scope wouldn't change, and remain 0 inc(&$i); # here $i is passed by reference, and would change to 1 [11] Support for multidimensional arrays. (Or as Andi calls them, 'hyperdimensional variables'.) The easiest way to define this support of PHP 3.0 is inductive - arrays can contain any type of variables, including other arrays. A simple example: $a[0]=5; $a[1]["testing"]=17; $b["foo"]=$a; Ok, so it may be not so simple. Play with it, it's pretty powerful. [12] Array initialization is now supported. For example, let's say you want to initialize a lookup table to convert number to month names: $months = array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"); would assign $months[0] to be January, $months[1] to be February, etc. Alternately, you may want the count to start at '1' instead of 0. You can do so easily: $months = array(1=>"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"); Also, you can specify an index for every entry, not just the first one: $first_names = array("Doe"=>"John", "Gates"=>"William", "Clinton"=>"Bill" }); would assign $first_names["Doe"]="John", etc. [13] Perl style lists now supported. Multiple values from arrays may now be assigned into several variables using one assignment. For example: $str = "johndoe:x:555:555:Doe, John:/home/johndoe:/bin/tcsh"; list($username,$passwd,$uid,$gid,$realname,$homedir,$shell) = explode(":",$str); Would assign 'johndoe' into $username, 'x' into $passwd, etc. [14] Colons are supported in 'case' and 'default' statements. For example: switch($value) { case 'A': statement; break; case 'B': statement; break; case 'C': statement; /* fall-through */ default: statement; } Semicolons are still supported, but when writing new scripts, they should be phased out in favour of colons. ------------------------------------------------------------------------------ Non Language Related New Features ================================= [1] Persistent resource lists. In plain english this means that there's now an easy way of writing the SQL drivers so that they don't open and close the SQL link every time, but instead open it the first time it's required, and then use it on every later hit. As of PHP 3.0a1, only the MySQL, mSQL and PostgresSQL drivers have been changed (rewritten) to take advantage of this option. To use it, use mysql_pconnect() instead of mysql_connect() (or the equivalents for the two other databases). [2] Configuration file. PHP now has its own configuration file, and many compile-time options of PHP2 are now configurable at runtime. [3] Syntax Highlighting. A syntax highlighter has been built into PHP 3.0, which means PHP 3.0 can display your code, syntax highlighted, instead of executing it. There are currently two ways to use the syntax highlighter. One is to use the show_source() statement. This statement is identical to the include() statement, except instead of executing the file, it displays its source syntax highlighted. The second way is possible only when running as an apache module, and is to define a special extension for PHP 3.0 source files (e.g. .php3s) and instruct apache to automatically syntax highlight them. [4] Loadable modules. This would have a huge impact on the Windows version, and would probably be used in the UNIX environment as well. One can now add PHP internal functions in runtime by loading a dynamic module. This is known to work under Solaris, Linux and Win32 at this time, but would be ported to any other capable platform if an incompatability is found. ------------------------------------------------------------------------------ Other Interesting Issues ======================== [1] Improved performance. The performance of PHP 3.0 is much better than the one of PHP/FI 2.0. Memory consumption has been dramatically reduced in many cases, due to the use of an internal memory manager, instead of apache's pools. Speedwise, PHP 3.0 is somewhere between 2 and 3 times faster than PHP/FI 2.0. [2] More reliable parser. After PHP 3.0 is well tested, it'll be pretty safe to say that it's more reliable than PHP/FI 2.0 is. While PHP/FI 2.0 performed well on simple, and fairly complex scripts, a fundamental design difference from PHP 3.0 makes it more prone to errors. In PHP 3.0, obscure parser problems are much less likely. [3] Improved C API. If you're a C coder, adding functionality to PHP was never easier. A pretty well documented API is available (apidoc.txt), and you no longer have to touch the parser or scanner code when adding your function. Also, it's more complicated to 'go wrong' when implementing a PHP3 function than it was in PHP2 (no stack to maintain) - but of course, you can mess up here too :) [4] Name change. PHP/FI 2.0 was renamed to PHP 3.0, and the meaning has changed from 'Personal Home Pages / Forms Interpreter' to 'PHP: Hypertext Preprocessor'. 'Personal' home pages was an understatement for PHP/FI 2.0, and is definitely an understatement for PHP 3.0.