Hello Steph, you forgot to mention the change in inheritance rules that affected the way interface ArrayAccess can be used. Due to a missing check in our inheritance rules 5.0.* series allowed to introduce return by reference in derived classes. Thus it was possible to implement offsetGet($offset) as function &offsetGet($offset).
right now []++ with overloaded objects is not possible due to a wrong limitation in the engine. This should be a bug and assigned to andi or dmitry. marcus Saturday, November 19, 2005, 3:20:42 PM, you wrote: > UPGRADE NOTES - PHP 5.1 > 1. Changes in reference handling > a. Overview > b. Code that worked under PHP 4.3, but now fails > c. Code that was valid under PHP 4.3, but now throws an error > d. Code that failed under PHP 4.3, but now works > e. Code that 'should have worked' under PHP 5.0 > f. Warnings that came and went > 2. String offset access > 3. Reading [] > 4. instanceof, is_a(), is_subclass_of(), catch > 5. Integer values in function parameters > 6. Abstract private methods > 7. Access modifiers in interfaces > 8. Extensions > a. Extensions that are gone from the PHP core > b. Class constants in new PHP 5.1 extensions > 9. Date/time support > 10. Changes in database support > a. PDO overview > b. Changes in MySQL support > c. Changes in SQLite support > 11. Further migration information > 12. Checking for E_STRICT errors > =============================================================================== > 1. Changes in reference handling > ================================ > 1a. Overview > ============ > From the PHP script writer's point of view, the change most likely to impact > legacy code is in the way that references are handled in all PHP versions > post-dating the PHP 4.4.0 release. > Until and including PHP 4.3, it was possible to send, assign or return > variables > by reference that should really be returned by value, such as a constant, a > temporary value (e.g. the result of an expression), or the result of a > function > that had itself been returned by value, as here: > <?php > $foo = "123"; > function return_value() { > global $foo; > return $foo; > } > $bar = &return_value(); ?>> > Although this code would usually work as expected under PHP 4.3, in the > general > case the result is undefined. The Zend Engine could not act correctly on these > values as references. This bug could and did lead to various hard-to-reproduce > memory corruption problems, particularly where the code base was large. > In PHP 4.4.0, PHP 5.0.4 and all subsequent PHP releases, the Engine was fixed > to 'know' when the reference operation is being used on a value that should > not be referenced. The actual value is now used in such cases, and a warning > is emitted. The warning takes the form of an E_NOTICE in PHP 4.4.0 and up, > and E_STRICT in PHP 5.0.4 and up. > Code that could potentially produce memory corruption can no longer do so. > However, some legacy code might work differently as a result. > 1b. Code that worked under PHP 4.3, but now fails > ================================================= > <?php > function func(&$arraykey) { > return $arraykey; // function returns by value! > } > $array = array('a', 'b', 'c'); > foreach (array_keys($array) as $key) { > $y = &func($array[$key]); > $z[] =& $y; > } > var_dump($z); ?>> > Running the above script under any version of PHP that pre-dates the reference > fix would produce this output: > array(3) { > [0]=> > &string(1) "a" > [1]=> > &string(1) "b" > [2]=> > &string(1) "c" > } > Following the reference fix, the same code would result in: > array(3) { > [0]=> > &string(1) "c" > [1]=> > &string(1) "c" > [2]=> > &string(1) "c" > } > This is because, following the changes, func() assigns by value. The value > of $y is re-assigned, and reference-binding is preserved from $z. Prior > to the fix, the value was assigned by reference, leading $y to be > re-bound on each assignment. The attempt to bind to a temporary value > by reference was the cause of the memory corruption. > Such code can be made to work identically in both the pre-fix and the > post-fix PHP versions. The signature of func() can be altered to return > by reference, or the reference assignment can be removed from the result > of func(). > <?php > function func() { > return 'function return'; > } > $x = 'original value'; > $y =& $x; > $y = &func(); > echo $x; ?>> > In PHP 4.3 $x would be 'original value', whereas after the changes it would > be 'function return' - remember that where the function does not return by > reference, the reference assignment is converted to a regular assignment. > Again, this can be brought to a common base, either by forcing func() to > return by reference or by eliminating the by-reference assignment. > 1c. Code that was valid under PHP 4.3, but now throws an error > ============================================================== > <?php > class Foo { > function getThis() { > return $this; > } > function destroyThis() { > $baz =& $this->getThis(); > } > } > $bar = new Foo(); > $bar->destroyThis(); > var_dump($bar); ?>> > In PHP 5.0.3, $bar evaluated to NULL instead of returning an object. > That happened because getThis() returns by value, but the value here > is assigned by reference. Although it now works in the expected way, > this is actually invalid code which will throw an E_NOTICE under > PHP 4.4 or an E_STRICT under PHP 5.0.4 and up. > 1d. Code that failed under PHP 4.3, but now works > ================================================= > <?php > function &f() { > $x = "foo"; > var_dump($x); > print "$x\n"; > return($a); > } > for ($i = 0; $i < 3; $i++) { > $h = &f(); > } ?>> > In PHP 4.3 the third call to var_dump produces NULL, due to the memory > corruption caused by returning an uninitialized value by reference. > This is valid code in PHP 5.0.4 and up, but threw errors in earlier > releases of PHP. > <?php > $arr = array('a1' => array('alfa' => 'ok')); > $arr =& $arr['a1']; > echo '-'.$arr['alfa']."-\n"; ?>> > Until PHP 5.0.5, it wasn't possible to assign an array element by > reference in this way. It now is. > 1e. Code that 'should have worked' under PHP 5.0 > ================================================ > There are a couple of instances of bugs reported under PHP 5.0 prior > to the reference fixes which now 'work'. However, in both cases errors > are thrown by PHP 5.1, because the code was invalid in the first place. > Returning values by reference using self:: now works in the general > case but throws an E_STRICT warning, and although your mileage may > vary when assigning by reference to an overloaded object, you will > still see an E_ERROR when you try it, even where the assignment > itself appears to work. > 1f. Warnings that came and went > =============================== > <?php > function & foo() { > $var = 'ok'; > return $var; > } > function & bar() { > return foo(); > } > $a =& bar(); > echo "$a\n"; ?>> > Nested calls to functions returning by reference are valid code under both > PHP 4.3 and PHP 5.1, but threw an unwarranted E_NOTICE or E_STRICT under > the intervening PHP releases. > 2. String offset access > ======================= > In PHP, both [] and {} can be used for accessing string offsets, e.g. > php -r "$str = "string"; echo $str{5}"; > and > php -r "$str = "string"; echo $str[5]"; > would both return the same result. This has led to many complaints over > inconsistent code in the past, and the [] syntax was deprecated some years > ago in an attempt to resolve the issue. However, it appears that [] is the > more popular means of accessing string offsets, so the decision has now > been made to deprecate the {} string offset syntax instead, with the > intention of removing it fully at a later date. > php -r "$str = "string"; echo $str{5}"; > will now return an E_STRICT message to that effect in PHP 5.1.0 and up, > and you are strongly discouraged from using this syntax in new code. > 3. Reading [] > ============= > <?php > class XmlTest { > function test_ref(&$test) { > $test = "ok"; > } > function test($test) { } > function run() { > $ar = array(); > $this->test_ref($ar[]); > var_dump($ar); > $this->test($ar[]); > } > } > $o = new XmlTest(); > $o->run(); ?>> > This should always have thrown a fatal E_ERROR, because [] cannot be used > for reading in PHP. It is invalid code in PHP 4.4.2 and PHP 5.0.5 upward. > 4. instanceof, is_a(), is_subclass_of(), catch > ============================================== > In PHP 5.0, is_a() was deprecated and replaced by the "instanceof" operator. > There were some issues with the initial implementation of "instanceof", which > relied on __autoload() to search for missing classes. If the class was not > present, "instanceof" would throw a fatal E_ERROR due to the failure of > __autoload() to discover that class. The same behaviour occurred in the > "catch" operator and the is_subclass_of() function, for the same reason. > None of these functions or operators call __autoload() in PHP 5.1, and > the class_exists() workarounds used in code written for PHP 5.0, while > not problematic in any way, are no longer necessary. > 5. Integer values in function parameters > ======================================== > With the advent of PHP 5.0, a new parameter parsing API was introduced > which is used by a large number of PHP functions. In all versions of > PHP between 5.0 and 5.1, the handling of integer values was very strict > and would reject non-well formed numeric values when a PHP function > expected an integer. These checks have now been relaxed to support > non-well formed numeric strings such as " 123" and "123 ", and will > no longer fail as they did under PHP 5.0. However, to promote code > safety and input validation, PHP functions will now emit an E_NOTICE > when such strings are passed as integers. > 6. Abstract private methods > =========================== > Abstract private methods were supported between PHP 5.0.0 and PHP 5.0.4, > but were then disallowed on the grounds that the behaviours of 'private' > and 'abstract' are mutually exclusive. > 7. Access modifiers in interfaces > ================================= > Under PHP 5.0, function declarations in interfaces were treated in exactly > the same way as function declarations in classes. This has not been the case > since [Oct 13th 2004], at which point only the 'public' access modifier was > allowed in interface function declarations. Since [April 26th 2005], the > 'static' modifier has also been allowed. However, the 'protected' and > 'private' > modifiers will now throw an E_ERROR, as will 'abstract'. Note that this change > should not affect your existing code, as none of these modifiers makes sense > in the context of interfaces anyway. > 8. Extensions > ============= > 8a. Extensions that are gone from the PHP core > ============================================== > One of the first things you're likely to notice when you download PHP 5.1 is > that > several of the older extensions have disappeared. Those extensions that are > still > actively maintained are available in the PHP Extension Community Library > (PECL), > at http://pecl.php.net. Windows binaries are built regularly, and you can > obtain > the binaries for PECL extensions built against PHP 5.1 from > http://pecl4win.php.net/list.php/5_1. > Extension Alternative/status > ========= ======================== > ext/cpdf pecl/pdflib > ext/dbx pecl/dbx > ext/dio pecl/dio > ext/fam not actively maintained > ext/ingres_ii pecl/ingres > ext/ircg not actively maintained > ext/mcve pecl/mcve > ext/mnogosearch not actively maintained > ext/oracle ext/oci8 or ext/pdo_oci > ext/ovrimos not actively maintained > ext/pfpro not actively maintained > - alternatives at > http://pecl.php.net/packages.php?catpid=18&catname=Payment > ext/w32api pecl/ffi > ext/yp not actively maintained > sapi/activescript pecl/phpscript > Modules in PECL that are not actively maintained (i.e. have not been supported > for some time, have no active maintainer working on them currently, and do not > have any PECL package releases), are still available in CVS at > http://cvs.php.net/pecl/. However, unreleased PHP modules are by their nature > unsupported, and your mileage may vary when attempting to install or use them. > 8b. Class constants in new PHP 5.1 extensions > ============================================= > The Zend Engine 2.1 API allows extension developers to declare class constants > in object oriented extensions. New extensions written for PHP 5.1, including > SPL, > PDO, ext/XMLReader and ext/date, have their constants in the format > PDO::CLASS_CONSTANT > rather than in the C format > PDO_CLASS_CONSTANT > in order to minimise pollution of the global namespace in PHP. > Note that the new Date class exists at this point purely to allow the core > date > extension to adhere to the above convention, although extended functionality > is planned for the the class in the future. > 9. Date/time support > ==================== > Date/time support has been fully rewritten in PHP 5.1, and no longer > uses the system settings to 'know' the timezone in operation. It will > instead utilize, in the following order: > * The timezone set using the date_default_timezone_set() function (if any) > * The TZ environment variable (if non empty) > * The date.timezone ini option (if set) > * "magical" guess (if the operating system supports it) > * If none of the above options succeeds, UTC > To ensure accuracy (and avoid an E_STRICT warning), you will need to define > your timezone in your php.ini using the following format: > date.timezone = Europe/London > The supported timezones are listed, in this format, in the PHP manual at > http://www.php.net/manual/en/timezones.php. > 10. Changes in database support > ============================== > 10a. PDO overview > ================ > PHP Data Objects (PDO) were introduced as a PECL extension under PHP 5.0, > and became part of the core PHP distribution in PHP 5.1. The PDO extension > provides a consistent interface for database access, and is used alongside > database-specific PDO drivers. Each driver may also have database-specific > functions of its own, but basic data access functionality such as issuing > queries and fetching data is covered by PDO functions, using the driver > named in PDO::__construct(). > You are encouraged to use PDO when creating new projects in PHP 5.1. Legacy > code will generally rely on the pre-existing database extensions, which are > still maintained. > Note that the PDO extension, and its drivers, are intended to be built as > shared extensions. This will enable straightforward driver upgrades from > PECL, without the need to rebuild PHP 5.1. > There is more in-depth information about the PDO extension in the manual > at http://www.php.net/manual/ref.pdo.php. > 10b. Changes in MySQL support > ============================ > In PHP 4, MySQL 3 support was built-in. With the release of PHP 5.0 there > were two MySQL extensions, named 'mysql' and 'mysqli', which were designed > to support MySQL < 4.1 and MySQL 4.1 and up, respectively. With the > introduction of PDO, which provides a very fast interface to all the > database APIs supported by PHP, the PDO_MYSQL driver can support any > of the current versions (MySQL 3, 4 or 5) in PHP code written for PDO, > depending on the MySQL library version used during compilation. The > older MySQL extensions remain in place for reasons of back compatibility, > but are not enabled by default. > 10c. Changes in SQLite support > ============================= > In PHP 5.0, SQLite 2 support was provided by the built-in sqlite > extension, which was also available as a PECL extension in PHP 4.3 > and PHP 4.4. With the introduction of PDO, the sqlite extension doubles > up to act as a 'sqlite2' driver for PDO; it is due to this that the > sqlite extension in PHP 5.1 has a dependency upon the PDO extension. > PHP 5.1 ships with a number of alternative interfaces to sqlite: > The sqlite extension provides the "classic" sqlite procedural/OO API > that you may have used in prior versions of PHP. It also provides the > PDO 'sqlite2' driver, which allows you to access legacy SQLite 2 > databases using the PDO API. > PDO_SQLITE provides the 'sqlite' version 3 driver. SQLite version 3 > is vastly superior to SQLite version 2, but the file formats of the > two versions are not compatible. > If your SQLite-based project is already written and working against > earlier PHP versions, then you can continue to use ext/sqlite without > problems, but will need to explicitly enable both PDO and sqlite. New > projects should use PDO and the 'sqlite' (version 3) driver, as this is > faster than SQLite 2, has improved locking concurrency, and supports > both prepared statements and binary columns natively. > 11. Further migration information > ================================ > For general information about migrating from PHP 4 to PHP 5, please refer to > the relevant section in the PHP manual at > http://www.php.net/manual/migration5.php. > 12. Checking for E_STRICT errors > ================================ > If you only have a single script to check, you can pick up E_STRICT > errors using PHP's commandline lint facility: > php -d error_reporting=4095 -l script_to_check.php > For larger projects, the shell script below will achieve the same task: > #!/bin/sh > directory=$1 > shift > # These extensions are checked > extensions="php inc" > check_file () > { > echo -ne "Doing PHP syntax check on $1 ..." > # Options: > ERRORS=`/www/php/bin/php -d display_errors=1 -d html_errors=0 -d > error_prepend_string=" " -d error_append_string=" " -d > error_reporting=4095 -l $1 | grep -v "No syntax errors detected"` > if test -z "$ERRORS"; then > echo -ne "OK." > else > echo -e "Errors found!\n$ERRORS" > fi > echo > } > # loop over remaining file args > for FILE in "$@" ; do > for ext in $extensions; do > if echo $FILE | grep "\.$ext$" > /dev/null; then > if test -f $FILE; then > check_file "$FILE" > fi > fi > done > done Best regards, Marcus -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php