PHP7不向下相容部分
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 >
- 不支援重複引數命名
需要手動檢查。
參考:
- 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,更高版本要繼續參考官方: