向后不兼容的改变

尽管大部分 PHP 4 的代码应该不用修改就能运行,还是应该留意以下向后不兼容的改变:

  • 有了一些新关键字

  • strrpos()strripos() 如今使用整个字符串作为 needle。

  • 非法使用字符串偏移量会导致 E_ERROR 而不是 E_WARNING。一个非法使用的例子:$str = 'abc'; unset($str[0]);.

  • array_merge() 被改成只接受数组。如果传递入非数组变量,对每个此类参数都会发出一条 E_WARNING 信息。要小心因为你的代码有可能疯狂发出 E_WARNING

  • PATH_TRANSLATED 服务器变量在 Apache2 SAPI 中不再暗中设定,这和 PHP 4 中的情形相反,如果 Apache 没产生此值则其被设为和 SCRIPT_FILENAME 服务器变量一样的值。此修改是为了遵守 CGI 规范。更多信息见 bug #23610,并参考手册中 $_SERVER['PATH_TRANSLATED'] 的说明。此问题也影响到 PHP >= 4.3.2 的版本。

  • Tokenizer 扩展不再定义 T_ML_COMMENT 常量。如果把 error_reporting 设为 E_ALL,PHP 将产生一条消息。尽管 T_ML_COMMENT 从来都没用到过,还是在 PHP 4 中定义了。在 PHP 4 和 PHP 5 中 // 和 /* */ 都被解析为 T_COMMENT 常量。但是 PHPDoc 风格的注释 /** */,自 PHP 5 开始被 PHP 解析,被识别为 T_DOC_COMMENT

  • 如果 variables_order 包括“S”,$_SERVER 应该带有 argc 和 argv 被产生。如果用户特别配制系统不创建 $_SERVER,那此变量当然就不存在了。改变的地方是不管 variables_order 怎么设定,在 CLI 版本中 argc 和 argv 总是可用的。本来 CLI 版不是总会产生全局变量 $argc 和 $argv 的。

  • 没有属性的对象不再被当成“empty”。

  • 有些情况下类必须在使用前被定义。这仅在使用了一些 PHP 5 的新特性的时候发生。其它情况下行为都没变。

  • get_class()get_parent_class()get_class_methods() 如今返回的类/方法名和定义时的名字一致(区分大小写),对于依赖以前行为(类/方法名总是返回小写的)的老脚本可能产生问题。一个可能的解决方法是在脚本中搜索所有这些函数并使用 strtolower()

    区分大小写的改变也适用于魔术常量 __CLASS____METHOD____FUNCTION__。其值都会严格按照定义时的名字返回(区分大小写)。

  • ip2long() 在传递入一个非法 IP 作为参数时返回 FALSE,不再是 -1

  • 如果在包含文件中定义有函数,则不管在 return() 之前还是之后都可以在主文件中调用。如果文件被包含两次,PHP 5 会发出致命错误,因为函数已经被定义,而 PHP 4 不管这个。因此推荐使用 include_once() 而不要去检查文件是否已被包含以及在包含文件中有条件返回。

  • include_once()require_once() 在 Windows 下先将路径规格化,因此包含 A.php 和 a.php 只会把文件包含一次。

例子 B-1. strrpos()strripos() 如今用整个字符串作为 needle

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

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

例子 B-2. 没有属性的对象不再被当成“empty”

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

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

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

例子 B-3. 有些情况下类必须在使用之前定义

<?php

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


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

interface c{
}
class
b implements c {
}

?>


add a note add a note User Contributed Notes
01-Mar-2006 06: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.
dward . maidencreek.com
02-Nov-2004 04:54
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.
08-Sep-2004 12: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:<br>";
       print_r($arr_gemerged);
       echo "<br>";

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:
john.g
27-Aug-2004 01:45
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.
cyberhorse
06-Aug-2004 01:07
clone() is a php function now.

if you create a subclass, it no longer uses samename methods in superclass as a constructor.
Justin Gehring
21-Jul-2004 04:34
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
jbeall /\t heraldic d0t us
15-Jul-2004 10:17
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.