PHP7不向下兼容部分
本文主要目标版本是7.1。
1. 类型声明
可以使用字符串(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,3.8);//str a=1.4 c+d=7.6;
s('a2','',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',string given
s('a5',[]);//Fatal error: Uncaught TypeError: Argument 4 passed to s() must be of the type float,array given
s('a6','');//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函数参数个数,调用的个数不满足声明的格式,会触发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 被移除
librariesPHPExcelSharedPCLZippclzip.lib.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,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,3];
foreach ($arr as $val) {
unset($arr[1]);
}
var_dump($arr);
//最新的PHP7依旧会打印出[1,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,3]而不是之前的[3,1]
list($arr[],$arr[],$arr[]) = [1,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 >
不支持重复参数命名
需要手动检查。
参考:
https://blog.csdn.net/u011957758/article/details/73320083
http://PHP.net/manual/en/migration70.changed-functions.PHP
http://PHP.net/manual/en/migration70.deprecated.PHP
http://PHP.net/manual/en/migration71.deprecated.PHP
本文目标版本是7.1,更高版本要继续参考官方: