php7發(fā)布已經升級到7.2.里面發(fā)生了很多的變化务蝠。本文整理php7.0至php7.2的新特性和一些變化霸奕。
參考資料:
http://php.net/manual/zh/migration70.new-features.php
http://php.net/manual/zh/migration71.new-features.php
http://php.net/manual/zh/migration72.new-features.php
PHP7.0
PHP7.0新特性
1. 組合比較符 (<=>)
組合比較符號用于比較兩個表達式蒲障。當$a小于、等于或大于$b時它分別返回-1曹抬、0或1,比較規(guī)則延續(xù)常規(guī)比較規(guī)則。對象不能進行比較
var_dump('PHP' <=> 'Node'); // int(1)
var_dump(123 <=> 456); // int(-1)
var_dump(['a', 'b'] <=> ['a', 'b']); // int(0)
2. null合并運算符
由于日常使用中存在大量同時使用三元表達式和isset操作重绷。使用null合并運算符可以簡化操作
# php7以前
if(isset($_GET['a'])) {
? $a = $_GET['a'];
}
# php7以前
$a = isset($_GET['a']) ? $_GET['a'] : 'none';
#PHP 7
$a = isset($_GET['a']) ?? 'none';
4.變量類型聲明
變量類型聲明有兩種模式慎框。一種是強制的,和嚴格的徒像。允許使用下列類型參數int黍特、string、float锯蛀、bool
同時不能再使用int灭衷、string、float旁涤、bool作為類的名字了
function sumOfInts(int ...$ints)
{
? ? return array_sum($ints);
}
var_dump(sumOfInts(2, '3', 4.1)); // int(9)
# 嚴格模式
declare(strict_types=1);
function add(int $x, int $y)
{
? ? return $x + $y;
}
var_dump(add('2', 3)); // Fatal error: Argument 1 passed to add() must be of the type integer
5.返回值類型聲明
增加了返回類型聲明翔曲,類似參數類型。這樣更方便的控制函數的返回值.在函數定義的后面加上:類型名即可
function fun(int $a): array
{
? return $a;
}
fun(3);//Fatal error
6.匿名類
php7允許new class {} 創(chuàng)建一個匿名的對象劈愚。
//php7以前
class Logger
{
? ? public function log($msg)
? ? {
? ? ? ? echo $msg;
? ? }
}
$util->setLogger(new Logger());
// php7+
$util->setLogger(new class {
? ? public function log($msg)
? ? {
? ? ? ? echo $msg;
? ? }
});
7.Unicode codepoint 轉譯語法
這接受一個以16進制形式的 Unicode codepoint瞳遍,并打印出一個雙引號或heredoc包圍的 UTF-8 編碼格式的字符串。 可以接受任何有效的 codepoint菌羽,并且開頭的 0 是可以省略的
echo "\u{aa}";// a
echo "\u{0000aa}";// a
echo "\u{9999}";// 香
8.Closure::call
閉包綁定 簡短干練的暫時綁定一個方法到對象上閉包并調用它掠械。
class A {private $x = 1;}
// PHP 7 之前版本的代碼
$getXCB = function() {return $this->x;};
$getX = $getXCB->bindTo(new A, 'A'); // 中間層閉包
echo $getX();
// PHP 7+ 及更高版本的代碼
$getX = function() {return $this->x;};
echo $getX->call(new A);
9.帶過濾的unserialize
提供更安全的方式解包不可靠的數據。它通過白名單的方式來防止?jié)撛诘拇a注入
// 將所有的對象都轉換為 __PHP_Incomplete_Class 對象
$data = unserialize($foo, ["allowed_classes" => false]);
// 將除 MyClass 和 MyClass2 之外的所有對象都轉換為 __PHP_Incomplete_Class 對象
$data = unserialize($foo, ["allowed_classes" => ["MyClass", "MyClass2"]);
// 默認情況下所有的類都是可接受的注祖,等同于省略第二個參數
$data = unserialize($foo, ["allowed_classes" => true]);
10.IntlChar類
這個類自身定義了許多靜態(tài)方法用于操作多字符集的 unicode 字符猾蒂。需要安裝intl拓展
printf('%x', IntlChar::CODEPOINT_MAX);
echo IntlChar::charName('@');
var_dump(IntlChar::ispunct('!'));
11.預期
它使得在生產環(huán)境中啟用斷言為零成本,并且提供當斷言失敗時拋出特定異常的能力氓轰。以后可以使用這個這個進行斷言測試
ini_set('assert.exception', 1);
class CustomError extends AssertionError {}
assert(false, new CustomError('Some error message'));
12.命名空間按組導入
從同一個命名空間下導入的類婚夫、函數、常量支持按組一次導入
#php7以前
use app\model\A;
use app\model\B;
#php7+
use app\model{A,B}
13.生成器支持返回表達式
它允許在生成器函數中通過使用 return 語法來返回一個表達式 (但是不允許返回引用值)署鸡, 可以通過調用 Generator::getReturn() 方法來獲取生成器的返回值案糙, 但是這個方法只能在生成器完成產生工作以后調用一次。
$gen = (function() {
? ? yield 1;
? ? yield 2;
? ? return 3;
})();
foreach ($gen as $val) {
? ? echo $val, PHP_EOL;
}
echo $gen->getReturn(), PHP_EOL;
# output
//1
//2
//3
14.生成器委派
現在靴庆,只需在最外層生成其中使用yield from时捌,就可以把一個生成器自動委派給其他的生成器
function gen()
{
? ? yield 1;
? ? yield 2;
? ? yield from gen2();
}
function gen2()
{
? ? yield 3;
? ? yield 4;
}
foreach (gen() as $val)
{
? ? echo $val, PHP_EOL;
}
15.整數除法函數intdiv
var_dump(intdiv(10,3)) //3
16.會話選項設置
session_start() 可以加入一個數組覆蓋php.ini的配置
session_start([
? ? 'cache_limiter' => 'private',
? ? 'read_and_close' => true,
]);
17.preg_replace_callback_array
可以使用一個關聯(lián)數組來對每個正則表達式注冊回調函數, 正則表達式本身作為關聯(lián)數組的鍵炉抒, 而對應的回調函數就是關聯(lián)數組的值
string preg_replace_callback_array(array $regexesAndCallbacks, string $input);
$tokenStream = []; // [tokenName, lexeme] pairs
$input = <<<'end'
$a = 3; // variable initialisation
end;
// Pre PHP 7 code
preg_replace_callback(
? ? [
? ? ? ? '~\$[a-z_][a-z\d_]*~i',
? ? ? ? '~=~',
? ? ? ? '~[\d]+~',
? ? ? ? '~;~',
? ? ? ? '~//.*~'
? ? ],
? ? function ($match) use (&$tokenStream) {
? ? ? ? if (strpos($match[0], '$') === 0) {
? ? ? ? ? ? $tokenStream[] = ['T_VARIABLE', $match[0]];
? ? ? ? } elseif (strpos($match[0], '=') === 0) {
? ? ? ? ? ? $tokenStream[] = ['T_ASSIGN', $match[0]];
? ? ? ? } elseif (ctype_digit($match[0])) {
? ? ? ? ? ? $tokenStream[] = ['T_NUM', $match[0]];
? ? ? ? } elseif (strpos($match[0], ';') === 0) {
? ? ? ? ? ? $tokenStream[] = ['T_TERMINATE_STMT', $match[0]];
? ? ? ? } elseif (strpos($match[0], '//') === 0) {
? ? ? ? ? ? $tokenStream[] = ['T_COMMENT', $match[0]];
? ? ? ? }
? ? },
? ? $input
);
// PHP 7+ code
preg_replace_callback_array(
[
? ? ? ? '~\$[a-z_][a-z\d_]*~i' => function ($match) use (&$tokenStream) {
? ? ? ? ? ? $tokenStream[] = ['T_VARIABLE', $match[0]];
? ? ? ? },
? ? ? ? '~=~' => function ($match) use (&$tokenStream) {
? ? ? ? ? ? $tokenStream[] = ['T_ASSIGN', $match[0]];
? ? ? ? },
? ? ? ? '~[\d]+~' => function ($match) use (&$tokenStream) {
? ? ? ? ? ? $tokenStream[] = ['T_NUM', $match[0]];
? ? ? ? },
? ? ? ? '~;~' => function ($match) use (&$tokenStream) {
? ? ? ? ? ? $tokenStream[] = ['T_TERMINATE_STMT', $match[0]];
? ? ? ? },
? ? ? ? '~//.*~' => function ($match) use (&$tokenStream) {
? ? ? ? ? ? $tokenStream[] = ['T_COMMENT', $match[0]];
? ? ? ? }
? ? ],$input);
18.隨機數奢讨、隨機字符函數
string random_bytes(int length);
int random_int(int min, int max);
19.define 支持定義數組
#php7+
define('ALLOWED_IMAGE_EXTENSIONS', ['jpg', 'jpeg', 'gif', 'png']);
#PHP7.0 變化
1.錯誤和異常處理相關變更
PHP 7 改變了大多數錯誤的報告方式。不同于傳統(tǒng)(PHP 5)的錯誤報告機制焰薄,現在大多數錯誤被作為 Error 異常拋出拿诸。
這也意味著扒袖,當發(fā)生錯誤的時候,以前代碼中的一些錯誤處理的代碼將無法被觸發(fā)亩码。 因為在 PHP 7 版本中季率,已經使用拋出異常的錯誤處理機制了。 (如果代碼中沒有捕獲 Error 異常描沟,那么會引發(fā)致命錯誤)飒泻。set_error_handle不一定接收的是異常,有可能是錯誤吏廉。
ERROR層級結構
interface Throwable
? ? |- Exception implements Throwable
? ? ? ? |- ...
? ? |- Error implements Throwable
? ? ? ? |- TypeError extends Error
? ? ? ? |- ParseError extends Error
? ? ? ? |- AssertionError extends Error
? ? ? ? |- ArithmeticError extends Error
? ? ? ? ? ? |- DivisionByZeroError extends ArithmeticError
function handler(Exception $e) { ... }
set_exception_handler('handler');
// 兼容 PHP 5 和 7
function handler($e) { ... }
// 僅支持 PHP 7
function handler(Throwable $e) { ... }
2.list
list 會按照原來的順序進行賦值泞遗。不再是逆序了
list($a,$b,$c) = [1,2,3];
var_dump($a);//1
var_dump($b);//2
var_dump($c);//3
list不再支持解開字符串、
3.foreach不再改變內部數組指針
<?php
$array = [0, 1, 2];
foreach ($array as &$val) {
? ? var_dump(current($array));
}
?>
#php 5
int(1)
int(2)
bool(false)
#php7
int(0)
int(0)
int(0)
4.十六進制字符串不再被認為是數字
var_dump("0x123" == "291");
#php5
true
#php7
false
5.$HTTP_RAW_POST_DATA 被移
$HTTP_RAW_POST_DATA 被移 使用php://input代替
6.移除了 ASP 和 script PHP 標簽
開標簽 閉標簽
<% %>
<%= %>
<script language="php"> </script>
##PHP7.1
PHP7.1新特性
1.可為空(Nullable)類型
參數以及返回值的類型現在可以通過在類型前加上一個問號使之允許為空席覆。當啟用這個特性時史辙,傳入的參數或者函數返回的結果要么是給定的類型,要么是null
#php5
function($a = null){
? if($a===null) {
? ? return null;
? }
? return $a;
}
#php7+
function fun() :?string
{
? return null;
}
function fun1(?$a)
{
? var_dump($a);
}
fun1(null);//null
fun1('1');//1
2.void 類型
返回值聲明為 void 類型的方法要么干脆省去 return 語句佩伤。對于 void來說髓霞,NULL 不是一個合法的返回值。
function fun() :void
{
? echo "hello world";
}
3. 類常量可見性
class Something
{
? ? const PUBLIC_CONST_A = 1;
? ? public const PUBLIC_CONST_B = 2;
? ? protected const PROTECTED_CONST = 3;
? ? private const PRIVATE_CONST = 4;
}
4.iterable 偽類
這可以被用在參數或者返回值類型中畦戒,它代表接受數組或者實現了Traversable接口的對象.
function iterator(iterable $iter)
{
? ? foreach ($iter as $val) {
? ? ? ? //
? ? }
}
5.多異常捕獲處理
一個catch語句塊現在可以通過管道字符(|)來實現多個異常的捕獲。 這對于需要同時處理來自不同類的不同異常時很有用
try {
? ? // some code
} catch (FirstException | SecondException $e) {
? ? // handle first and second exceptions
}
6.list支持鍵名
$data = [
? ? ["id" => 1, "name" => 'Tom'],
? ? ["id" => 2, "name" => 'Fred'],
];
// list() style
list("id" => $id1, "name" => $name1) = $data[0];
var_dump($id1);//1
7.字符串支持負向
$a= "hello";
$a[-2];//l
8.將callback 轉閉包
Closure新增了一個靜態(tài)方法结序,用于將callable快速地 轉為一個Closure 對象障斋。
<?php
class Test
{
? ? public function exposeFunction()
? ? {
? ? ? ? return Closure::fromCallable([$this, 'privateFunction']);
? ? }
? ? private function privateFunction($param)
? ? {
? ? ? ? var_dump($param);
? ? }
}
$privFunc = (new Test)->exposeFunction();
$privFunc('some value');
9. http2 服務推送
對http2服務器推送的支持現在已經被加入到 CURL 擴展
##PHP7.1變更
1.傳遞參數過少時將拋出錯誤
過去我們傳遞參數過少 會產生warning。php7.1開始會拋出error
2.移除了ext/mcrypt拓展
#PHP7.2
PHP7.2新特性
1.增加新的類型object
function test(object $obj) : object
{
? ? return new SplQueue();
}
test(new StdClass());
2.通過名稱加載擴展
擴展文件不再需要通過文件加載 (Unix下以.so為文件擴展名徐鹤,在Windows下以 .dll 為文件擴展名) 進行指定垃环。可以在php.ini配置文件進行啟用
; ini file
extension=php-ast
zend_extension=opcache
3.允許重寫抽象方法
當一個抽象類繼承于另外一個抽象類的時候返敬,繼承后的抽象類可以重寫被繼承的抽象類的抽象方法遂庄。
<?php
abstract class A
{
? ? abstract function test(string $s);
}
abstract class B extends A
{
? ? // overridden - still maintaining contravariance for parameters and covariance for return
? ? abstract function test($s) : int;
}
4.使用Argon2算法生成密碼散列
Argon2 已經被加入到密碼散列(password hashing) API (這些函數以 password_ 開頭), 以下是暴露出來的常量
5.新增 PDO 字符串擴展類型
當你準備支持多語言字符集,PDO的字符串類型已經擴展支持國際化的字符集劲赠。以下是擴展的常量:
PDO::PARAM_STR_NATL
PDO::PARAM_STR_CHAR
PDO::ATTR_DEFAULT_STR_PARAM
$db->quote('über', PDO::PARAM_STR | PDO::PARAM_STR_NATL);
6.命名分組命名空間支持尾部逗號
use Foo\Bar\{
? ? Foo,
? ? Bar,
? ? Baz,
};
#PHP7.2 變更
1.number_format 返回值
var_dump(number_format(-0.01)); // now outputs string(1) "0" instead of string(2) "-0"
2.get_class()不再允許null涛目。
var_dump(get_class(null))// warning
4 count 作用在不是 Countable Types 將發(fā)生warning
count(1), // integers are not countable
5.不帶引號的字符串
在之前不帶引號的字符串是不存在的全局常量,轉化成他們自身的字符串×菖欤現在將會產生waring霹肝。
var_dump(HEELLO);
6.__autoload 被廢棄
__autoload方法已被廢棄
7.each 被廢棄
使用此函數遍歷時,比普通的 foreach 更慢塑煎, 并且給新語法的變化帶來實現問題沫换。因此它被廢棄了。
8.is_object最铁、gettype修正
is_object 作用在**__PHP_Incomplete_Class** 將反正 true
gettype作用在閉包在將正確返回resource
9.Convert Numeric Keys in Object/Array Casts
把數組轉對象的時候讯赏,可以訪問到整型鍵的值垮兑。
// array to object
$arr = [0 => 1];
$obj = (object)$arr;
var_dump(
? ? $obj,
? ? $obj->{'0'}, // now accessible
? ? $obj->{0} // now accessible
);