PHP7不向下兼容部分

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xuduorui/article/details/85460401

PHP7不向下兼容部分

本文主要目标版本是7.1。

1. 类型声明

PHP7下要求函数实参类型与声明了类型的形参类型一致。
可以使用字符串(string), 整数 (int), 浮点数 (float), 以及布尔值 (bool),数组(array),来声明函数的参数类型与函数返回值。

function s(string $a, array $b, int $c, float $d) {
    echo "str a=$a c+d=".($c*$d).";\n";
}
s([], [], 2, 3.8);//Fatal error: Uncaught TypeError: Argument 1 passed to s() must be of the type string, array given
s(1.4, [], 2, 3.8);//str a=1.4 c+d=7.6;
s('a2', '', 2, 3.8);//Fatal error: Uncaught TypeError: Argument 2 passed to s() must be of the type array, string given
s('a3', [], [], 3.8);//Fatal error: Uncaught TypeError: Argument 3 passed to s() must be of the type integer, array given
s('a4', [], '', 3.8);//Fatal error: Uncaught TypeError: Argument 3 passed to s() must be of the type integer, string given
s('a5', [], 2, []);//Fatal error: Uncaught TypeError: Argument 4 passed to s() must be of the type float, array given
s('a6', [], 2, '');//Fatal error: Uncaught TypeError: Argument 4 passed to s() must be of the type float, string given
s('a7', [], 2.9, 3.8);//str a=a7 c+d=7.6;//2.9被当做整形2处理

使用严格模式:declare(strict_types=1);

declare(strict_types=1);
function add(int $a, int $b): int {
    return $a+$b;
}
echo add(1, 2);
echo add(1.9, 2.6);

php5是无法执行上面代码的,php7执行的时候会先输出一个3和一个报错( Argument 1 passed to add() must be of the type integer, float given);
标量类型声明 有两种模式: 强制 (默认) 和 严格模式。
declare(strict_types=1),必须放在文件的第一行执行代码,当前文件有效!
每个文件声明declare(strict_types=1)不是个理想的解决办法。

使用phan可以扫描出以上错误。

必须手动检查和修改。
int<->float不会fatal,但是会位数损失。int|flot<->string|array会fatal。

grep -w int -rn ./ -rn | grep -w function | grep -v -e .git -e .js -e .html -e '@' -e .as | less

array使用很多:

grep -w array -rn ./ -rn | grep -w function | grep -v -e .git -e .js -e .html -e '@' -e .as -e 'array()' | less

float,double,string,bool使用无。
从phan的扫描结果中检查。

2. 类型声明后跨类型使用

PHP7下申明对象后,将对象当成另一种类型使用会报出Fatal错误。主要在array类型。
错误用法如下:

$wheres = '';
$wheres[] = ' 1 and aStatus=1';

以下用法是容忍的,会Notice或Warning,不会Fatal:

$a = 'a';
$a = 1; 
$a = $a[1];// 返回空
$a = [3];
$a++;// 对数组++无效

必须手动检查和修改。

grep -w int -rn ./ -rn | grep -w function | grep -v -e .git -e .js -e .html -e '@' | less

可以从phan的扫描结果中检查。

3. 函数限制

PHP7不能使用同名的构造函数
PHP7实例方法不能用静态方法的方式调用
PHP7函数参数个数,调用的个数不满足声明的格式,会触发Fatal

function s(string $a, array $b) {
    echo "str a=$a;\n";
}
s(1);

//Uncaught ArgumentCountError: Too few arguments to function s()

需要手动检查。
从phan的扫描结果中检查。

4. 不兼容函数

4.1 mcrypt_系列被移除

mcrypt_generic_end()
mcrypt_ecb()
mcrypt_cbc()
mcrypt_cfb()
mcrypt_ofb()

搜索: mcrypt_*

grep mcrypt_ -rn ./ -rn | grep -v -e .git -e .js -e .html -e '@' -e .as | less

使用openssh系列替换。

4.2 set_exception_handler() 不再保证收到的一定是 Exception 对象

PHP5下原型是:
set_exception_handler(function (Exception $e) {…})
PHP7下原型是:
set_exception_handler(function (Throwable $e) {…})

4.3 set_magic_quotes_runtime 被移除

4.4 set_socket_blocking 被移除

\libraries\PHPExcel\Shared\PCLZip\pclzip.lib.php
\libraries\PHPMailer\Client.php

4.5 split 被移除

4.6 imageps* 被移除

imagepsbbox()
imagepsencodefont()
imagepsextendfont()
imagepsfreefont()
imagepsloadfont()
imagepsslantfont()
imagepstext()

4.7 mktime()参数变化

mktime() gmmktime() 不再接受$is_dst参数

4.8 shmop_函数返回变化

shmop_open() The return type of shmop_open() has been changed from int to resource.

4.9 setlocale() 函数

不再接受 category 传入字符串。 应当使用 LC_* 常量。

4.10 xml_set_object

为了避免内存泄露,xml_set_object() 现在在执行结束时需要手动清除 $parse。

4.11 curl_setopt

curl_setopt 设置项CURLOPT_SAFE_UPLOAD变更:
TRUE 禁用 @ 前缀在 CURLOPT_POSTFIELDS 中发送文件。 意味着 @ 可以在字段中安全得使用了。 可使用 CURLFile作为上传的代替。
PHP 5.5.0 中添加,默认值 FALSE。 PHP 5.6.0 改默认值为 TRUE。. PHP 7 删除了此选项, 必须使用 CURLFile interface 来上传文件。
curl_setopt 中CURLOPT_HTTPHEADER变更:
值必须是array,否则会出发warning

4.12 preg_函数变化

preg_replace() 函数不再支持 “\e” (PREG_REPLACE_EVAL). 应当使用 preg_replace_callback() 替代。

需要手动检查。

for file in `grep -w 'preg_replace' -rn * | grep -v -e '.js:' -e '.html:' -e '.css:'  |awk -F ':' '{print $1}' | sort | uniq`; do echo grep "$file"; grep '/e' "$file" -n ; done

4.13 Eval option for mb_ereg_replace() and mb_eregi_replace()

4.14 xml_parser_free

xml_parser_free() is no longer sufficient to free the parser resource, if it references an object and this object references that parser resource. In this case it is necessary to additionally unset the $parser.

这个函数不能满足释放xml parser资源,需要用unset($parser)方法。

grep 'xml_parser_free' -rn ./ -rn | grep -v -e .git -e .js -e .html -e '@' -e .as | less

5 HTTP_RAW_POST_DATA

HTTP_RAW_POST_DATA替代为file_get_contents(‘php://input’)

grep -w HTTP_RAW_POST_DATA -rn ./ -rn | grep -v -e .git -e .js -e .html -e '@' -e .as | less

详细可参考:
http://www.nowamagic.net/academy/detail/12220520

6 foreach 修改

foreach()循环对数组内部指针不再起作用

$arr = [1,2,3];
foreach ($arr as &$val) {
    echo current($arr);// php7 全返回0
}
for i in `grep -w current -rn ./ -rn | grep -v -e .git -e .js -e .html -e '@' -e .as | grep 'current  (' | awk -F ':' '{print $1}' | sort | uniq `; do echo $i; grep  'foreach.*&' $i -n ; done

按照值进行循环的时候, foreach是对该数组的拷贝操作

$arr = [1,2,3];
foreach ($arr as $val) {
    unset($arr[1]);
}
var_dump($arr);
//最新的php7依旧会打印出[1,2,3]。(ps:7.0.0不行) 老的会打印出[1,3]

按照引用进行循环的时候, 对数组的修改会影响循环

$arr = [1];
foreach ($arr as $val) {
    var_dump($val);
    $arr[1]=2;
}
//最新的php7依旧会追加新增元素的循环。(ps:7.0.0不行)

7 list修改

不再按照相反的顺序赋值

//$arr将会是[1,2,3]而不是之前的[3,2,1]
list($arr[], $arr[], $arr[]) = [1,2,3];

不再支持字符串拆分功能。

// $x = null 并且 $y = null
$str = 'xy';
list($x, $y) = $str;

空的list()赋值不再允许,手动检查。

list() = [123];//php7不允许
grep 'list(' -rn ./ -rn | grep -v -e .git -e .js -e .html -e '@' -e .as | grep -w list | less

8 变量语法处理机制修改

对变量、属性和方法的间接调用现在将严格遵循从左到右的顺序来解析,而不是之前的混杂着几个特殊案例的情况。 下面这张表说明了这个解析顺序的变化。

引用赋值时自动创建的数组元素或者对象属性顺序和以前不同了

$arr = [];
$arr['a'] = &$arr['b'];
$arr['b'] = 1;
// php7: ['a' => 1, 'b' => 1]
// php5: ['b' => 1, 'a' => 1]

需要手动检查。

9 其他

  • 移除了ASP格式的支持和脚本语法的支持: <% 和 < script language=php >
  • 不支持重复参数命名

需要手动检查。

参考:

本文目标版本是7.1,更高版本要继续参考官方:

猜你喜欢

转载自blog.csdn.net/xuduorui/article/details/85460401
今日推荐