Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Appendices : Migrating from PHP 4 to PHP 5 : Backward Incompatible Changes

Backward Incompatible Changes

Although most existing PHP 4 code should work without changes, you should pay attention to the following backward incompatible changes:

  • There are some new reserved keywords.
  • strrpos() and strripos() now use the entire string as a needle.
  • Illegal use of string offsets causes E_ERROR instead of E_WARNING. An example illegal use is: $str = 'abc'; unset($str[0]);.
  • array_merge() was changed to accept only arrays. If a non-array variable is passed, a E_WARNING will be thrown for every such parameter. Be careful because your code may start emitting E_WARNING out of the blue.
  • PATH_TRANSLATED server variable is no longer set implicitly under Apache2 SAPI in contrast to the situation in PHP 4, where it is set to the same value as the SCRIPT_FILENAME server variable when it is not populated by Apache. This change was made to comply with the » CGI specification. Please refer to » bug #23610 for further information, and see also the $_SERVER['PATH_TRANSLATED'] description in the manual. This issue also affects PHP versions >= 4.3.2.
  • The T_ML_COMMENT constant is no longer defined by the Tokenizer extension. If error_reporting is set to E_ALL, PHP will generate a notice. Although the T_ML_COMMENT was never used at all, it was defined in PHP 4. In both PHP 4 and PHP 5 // and /* */ are resolved as the T_COMMENT constant. However the PHPDoc style comments /** */, which starting PHP 5 are parsed by PHP, are recognized as T_DOC_COMMENT.
  • $_SERVER should be populated with argc and argv if variables_order includes "S". If you have specifically configured your system to not create $_SERVER, then of course it shouldn't be there. The change was to always make argc and argv available in the CLI version regardless of the variables_order setting. As in, the CLI version will now always populate the global $argc and $argv variables.
  • An object with no properties is no longer considered "empty".
  • In some cases classes must be declared before use. It only happens if some of the new features of PHP 5 (such as interfaces) are used. Otherwise the behaviour is the old.
  • get_class(), get_parent_class() and get_class_methods() now return the name of the classes/methods as they were declared (case-sensitive) which may lead to problems in older scripts that rely on the previous behaviour (the class/method name was always returned lowercased). A possible solution is to search for those functions in all your scripts and use strtolower().

    This case sensitivity change also applies to the magical predefined constants __CLASS__, __METHOD__, and __FUNCTION__. The values are returned exactly as they're declared (case-sensitive).

  • ip2long() now returns FALSE when an invalid IP address is passed as argument to the function, and no longer -1.
  • If there are functions defined in the included file, they can be used in the main file independent if they are before return() or after. If the file is included twice, PHP 5 issues fatal error because functions were already declared, while PHP 4 doesn't complain about it. It is recommended to use include_once() instead of checking if the file was already included and conditionally return inside the included file.
  • include_once() and require_once() first normalize the path of included file on Windows so that including A.php and a.php include the file just once.

Example D.1. strrpos() and strripos() now use the entire string as a needle

<?php
var_dump
(strrpos('ABCDEF','DEF')); //int(3)

var_dump(strrpos('ABCDEF','DAF')); //bool(false)
?>


Example D.2. An object with no properties is no longer considered "empty"

<?php
class test { }
$t = new test();

var_dump(empty($t)); // echo bool(false)

if ($t) {
   
// Will be executed
}
?>


Example D.3. In some cases classes must be declared before used

<?php

//works with no errors:
$a = new a();
class
a {
}


//throws an error:
$a = new b();

interface
c{
}
class
b implements c {
}

?>


Code Examples / Notes » migration5.incompatible

kemal djakman

The handling of accessing empty property of a class error has also changed:
<?php
class Foo {
var $Bar = 'xxx';
function F() {
echo $this->$Bar;
}
}
$Obj = new Foo();
$Obj->F();
?>
Notice the $ sign after object dereference opr?  $Bar is empty inside method F.   PHP4 would only generate a warning, PHP5 throws a fatal error


amir laher

Some other things to be aware of:
some extra strictness:
* object members can no longer be accessed using array-member syntax
* function-calls with too many arguments will now cause errors.
Also, from PHP5.2, custom session handlers are affected:
* Best not to use global objects in custom session-handling functions. These would get destructed *before* the session is written (unless session_write_close() is called explicitly).


john.g

PATH_TRANSLATED is handy when using Apache's ModRewrite engine, as it gives you the name and path of the resulting file rather than the one that was requested by the user. Since PHP 5.0 and Apache 2 no longer support this variable, I created a workaround by adding an environment variable to my ModRewrite command:
Original:
RewriteRule ^/test/(.*)\.php(.*) /test/prefix_$1.php$2
Adjusted:
RewriteRule ^/test/(.*)\.php(.*) /test/prefix_$1.php$2 [E=TARGET:prefix_$1.php]
I could then find out the resulting file name through the super global $_ENV, for instance:
<?php
echo "The actual filename is ".$_ENV['REDIRECT_TARGET'];
?>
Note: The "REDIRECT_" prefix appears to be allocated automatically by ModRewrite.


justin gehring

One more thing that is not backwards compatible with PHP 5.0 (at least as far as we can tell) is the XSLT Sablotron librarys and the old DOM_XML librarys. Both have replacements, but translations will need to be made with either an alias class, or in the code itself.
-Justin Gehring


sinured

Not mentioned above: The PHP/FI 2 function style (old_function aka cfunction) is no longer supported as of PHP 5.

28-feb-2006 10:03

is_a have been deprecated. You can simply replace all occurences with the new instanceOf operator, although this will break backwards-compatibility with php4.

cyberhorse

clone() is a php function now.
if you create a subclass, it no longer uses samename methods in superclass as a constructor.


07-sep-2004 05:40

Be careful with array_merge in PHP5.1 not only a E_WARNING is thrown, but also the result is an empty array. So if you merge two select queries and the last one is empty you will end up with no array at all.
$array_1 = array('key1'=>'oranges','key2'=>'apples');
       $array_2 = array('key3'=>'pears','key4'=>'tomatoes');
       $array_3 = null;
       $arr_gemerged = array_merge($array_1,$array_2,$array_3);
       echo "result:
";
       print_r($arr_gemerged);
       echo "
";
Result on php4:
result:
Array ( [key1] => oranges [key2] => apples [key3] => pears [key4] => tomatoes )
Result on php5:
Warning: array_merge() [function.array-merge]: Argument #3 is not an array in /Library/WebServer/Documents/regis24/admin/test_array_merge.php on line 7
result:


aggelos orfanakos

As with array_merge(), array_merge_recursive() returns NULL in PHP 5 if a non-array parameter is passed to it.

dward . maidencreek.com

Another change that we've had problems with while trying to use PHP4 code in PHP5 is how $this is carried across static method calls if they are not declared static in PHP5.  The main issue was that debug_backtrace() now shows the first class with -> instead of the second with :: in the backtrace element when the method in the second class was called statically (using ::) from a method in the first class.

jbeall /\t heraldic d0t us

Another change that was made is the behavior when you try to reassign $this.
Before, you could reassign $this from within an object, and thus change it to a different class.  Now, this results in a parse error.


nami

addition of the note on 07-Sep-2004 06:40
if you write down your code like this PHP5 will just work fine:
    $array_1 = array('key1'=>'oranges','key2'=>'apples');
    $array_2 = array('key3'=>'pears','key4'=>'tomatoes');
    $array_3 = array();
    $arr_gemerged = array_merge($array_1,$array_2,$array_3);
    echo "result:
";
    print_r($arr_gemerged);
    echo "
";
---
so you have to declare array_3 as array() instead of NULL


Change Language


Follow Navioo On Twitter
What has changed in PHP 5
Backward Incompatible Changes
CLI and CGI
Migrating Configuration Files
New Functions
New Directives
Databases
New Object Model
Error Reporting
eXTReMe Tracker