PHP特性整合(PHP5.X到PHP7.1.x)

Buid-in web server內置了一個簡單的Web服務器

把當前目錄做爲Root Document只須要這條命令便可:javascript

php -S localhost:3300

 

也能夠指定其它路徑php

php -S localhost:3300 -t /path/to/root 

 

還能夠指定路由css

php -S localhost:3300 router.php

 

命名空間(php5.3)

命名空間的分隔符爲反斜杆\html

namespace fox\lanmps\Table; class Select {}

 

獲取完整類別名稱

PHP5.3 中引入命名空間的別名類和命名空間短版本的功能。雖然這並不適用於字符串類名稱java

use Some\Deeply\Nested\Namespace\FooBar;    
// does not work, because this will try to use the global `FooBar` class $reflection = new ReflectionClass('FooBar'); echo FooBar::class; 

 

爲了解決這個問題採用新的FooBar::class語法,它返回類的完整類別名稱mysql

命名空間 use 操做符開始支持函數和常量的導入

namespace Name\Space { const FOO = 42; function f() { echo __FUNCTION__."\n"; } } namespace { use const Name\Space\FOO; use function Name\Space\f; echo FOO."\n"; f(); } 

 

輸出 
42 
Name\Space\fweb

Group use declarations

從同一 namespace 導入的類、函數和常量如今能夠經過單個 use 語句 一次性導入了。正則表達式

//PHP7以前 use some\namespace\ClassA; use some\namespace\ClassB; use some\namespace\ClassC as C; use function some\namespace\fn_a; use function some\namespace\fn_b; use function some\namespace\fn_c; use const some\namespace\ConstA; use const some\namespace\ConstB; use const some\namespace\ConstC; // PHP7以後 use some\namespace\{ClassA, ClassB, ClassC as C}; use function some\namespace\{fn_a, fn_b, fn_c}; use const some\namespace\{ConstA, ConstB, ConstC};

 

支持延遲靜態綁定

static關鍵字來引用當前類,即實現了延遲靜態綁定算法

class A { public static function who() { echo __CLASS__; } public static function test() { static::who(); // 這裏實現了延遲的靜態綁定 } } class B extends A { public static function who() { echo __CLASS__; } } B::test(); 

輸出結果: 
Bsql

支持goto語句

多數計算機程序設計語言中都支持無條件轉向語句goto,當程序執行到goto語句時,即轉向由goto語句中的標號指出的程序位置繼續執行。儘管goto語句有可能會致使程序流程不清晰,可讀性減弱,但在某些狀況下具備其獨特的方便之處,例如中斷深度嵌套的循環和 if 語句。

goto a; echo 'Foo'; a: echo 'Bar'; for($i=0,$j=50; $i<100; $i++) { while($j--) { if($j==17) goto end; } } echo "i = $i"; end: echo 'j hit 17'; 

支持閉包、Lambda/Anonymous函數

閉包(Closure)函數和Lambda函數的概念來自於函數編程領域。例如JavaScript 是支持閉包和 lambda 函數的最多見語言之一。 
在PHP中,咱們也能夠經過create_function()在代碼運行時建立函數。但有一個問題:建立的函數僅在運行時才被編譯,而不與其它代碼同時被編譯成執行碼,所以咱們沒法使用相似APC這樣的執行碼緩存來提升代碼執行效率。 
在PHP5.3中,咱們可使用Lambda/匿名函數來定義一些臨時使用(即用即棄型)的函數,以做爲array_map()/array_walk()等函數的回調函數。

echo preg_replace_callback('~-([a-z])~', function ($match) { return strtoupper($match[1]); }, 'hello-world'); // 輸出 helloWorld $greet = function($name) { printf("Hello %s\r\n", $name); }; $greet('World'); $greet('PHP'); //...在某個類中 $callback = function ($quantity, $product) use ($tax, &$total) { $pricePerItem = constant(__CLASS__ . "::PRICE_" . strtoupper($product)); $total += ($pricePerItem * $quantity) * ($tax + 1.0); }; 

 

魔術方法__callStatic()和__invoke()

PHP中本來有一個魔術方法__call(),當代碼調用對象的某個不存在的方法時該魔術方法會被自動調用。新增的__callStatic()方法則只用於靜態類方法。當嘗試調用類中不存在的靜態方法時,__callStatic()魔術方法將被自動調用。

class MethodTest { public function __call($name, $arguments) { // 參數 $name 大小寫敏感 echo "調用對象方法 '$name' " . implode(' -- ', $arguments). "\n"; } /** PHP 5.3.0 以上版本中本類方法有效 */ public static function __callStatic($name, $arguments) { // 參數 $name 大小寫敏感 echo "調用靜態方法 '$name' " . implode(' -- ', $arguments). "\n"; } } $obj = new MethodTest; $obj->runTest('經過對象調用'); MethodTest::runTest('靜態調用'); // As of PHP 5.3.0

 

以上代碼執行後輸出以下: 
調用對象方法’runTest’ –- 經過對象調用調用靜態方法’runTest’ –- 靜態調用 
以函數形式來調用對象時,__invoke()方法將被自動調用。

class MethodTest { public function __call($name, $arguments) { // 參數 $name 大小寫敏感 echo "Calling object method '$name' " . implode(', ', $arguments). "\n"; } /** PHP 5.3.0 以上版本中本類方法有效 */ public static function __callStatic($name, $arguments) { // 參數 $name 大小寫敏感 echo "Calling static method '$name' " . implode(', ', $arguments). "\n"; } } $obj = new MethodTest; $obj->runTest('in object context'); MethodTest::runTest('in static context'); // As of PHP 5.3.0 

 

Nowdoc語法

用法和Heredoc相似,但使用單引號。Heredoc則須要經過使用雙引號來聲明。 
Nowdoc中不會作任何變量解析,很是適合於傳遞一段PHP代碼。

// Nowdoc 單引號 PHP 5.3以後支持 $name = 'MyName'; echo <<<'EOT' My name is "$name". EOT; //上面代碼輸出 My name is "$name". ((其中變量不被解析) // Heredoc不加引號 echo <<<FOOBAR Hello World! FOOBAR; //或者 雙引號 PHP 5.3以後支持 echo <<<"FOOBAR" Hello World! FOOBAR; 

 

支持經過Heredoc來初始化靜態變量、類成員和類常量。

// 靜態變量 function foo() { static $bar = <<<LABEL Nothing in here... LABEL; } // 類成員、常量 class foo { const BAR = <<<FOOBAR Constant example FOOBAR; public $baz = <<<FOOBAR Property example FOOBAR; } 

 

在類外也可以使用const來定義常量

//PHP中定義常量一般是用這種方式 define("CONSTANT", "Hello world."); //而且新增了一種常量定義方式 const CONSTANT = 'Hello World'; 

 

三元運算符增長了一個快捷書寫方式

本來格式爲是(expr1) ? (expr2) : (expr3) 
若是expr1結果爲True,則返回expr2的結果。 
新增一種書寫方式,能夠省略中間部分,書寫爲expr1 ?: expr3 
若是expr1結果爲True,則返回expr1的結果

$expr1=1; $expr2=2; //原格式 $expr=$expr1?$expr1:$expr2 //新格式 $expr=$expr1?:$expr2

輸出結果: 

1

空合併運算符(??)

簡化判斷

$param = $_GET['param'] ?? 1;

 

至關於:

$param = isset($_GET['param']) ? $_GET['param'] : 1;

 

Json更懂中文(JSON_UNESCAPED_UNICODE)

echo json_encode("中文", JSON_UNESCAPED_UNICODE); //輸出:"中文" 

 

二進制

$bin = 0b1101; echo $bin; //13 

Unicode codepoint 轉譯語法

這接受一個以16進制形式的 Unicode codepoint,並打印出一個雙引號或heredoc包圍的 UTF-8 編碼格式的字符串。 能夠接受任何有效的 codepoint,而且開頭的 0 是能夠省略的。

echo "\u{9876}"

 

舊版輸出:\u{9876} 
新版輸入:頂

使用 ** 進行冪運算

加入右鏈接運算符 * 來進行冪運算。 同時還支持簡寫的 *= 運算符,表示進行冪運算並賦值。

printf("2 ** 3 == %d\n", 2 ** 3); printf("2 ** 3 ** 2 == %d\n", 2 ** 3 ** 2); $a = 2; $a **= 3; printf("a == %d\n", $a);

 

輸出 
2 ** 3 == 8 
* 3 * 2 == 512 
a == 8

太空船操做符(組合比較符)

太空船操做符用於比較兩個表達式。當 ab 時它分別返回 -1 、 0 或 1 。 比較的原則是沿用 PHP 的常規比較規則進行的。

// Integers echo 1 <=> 1; // 0 echo 1 <=> 2; // -1 echo 2 <=> 1; // 1 // Floats echo 1.5 <=> 1.5; // 0 echo 1.5 <=> 2.5; // -1 echo 2.5 <=> 1.5; // 1 // Strings echo "a" <=> "a"; // 0 echo "a" <=> "b"; // -1 echo "b" <=> "a"; // 1

 

Traits

Traits提供了一種靈活的代碼重用機制,即不像interface同樣只能定義方法但不能實現,又不能像class同樣只能單繼承。至於在實踐中怎樣使用,還須要深刻思考。 
魔術常量爲TRAIT

官網的一個例子:  
trait SayWorld { public function sayHello() { parent::sayHello(); echo "World!\n"; echo 'ID:' . $this->id . "\n"; } } class Base { public function sayHello() { echo 'Hello '; } } class MyHelloWorld extends Base { private $id; public function __construct() { $this->id = 123456; } use SayWorld; } $o = new MyHelloWorld(); $o->sayHello(); /*will output: Hello World! ID:123456 */ 

 

array 數組簡寫語法

$arr = [1,'james', 'james@fwso.cn']; $array = [   "foo" => "bar",   "bar" => "foo"   ]; 

 

array 數組中某個索引值簡寫

function myfunc() { return array(1,'james', 'james@fwso.cn'); } echo myfunc()[1]; $name = explode(",", "Laruence,male")[0]; explode(",", "Laruence,male")[3] = "phper"; 

 

非變量array和string也能支持下標獲取了

echo array(1, 2, 3)[0];  
echo [1, 2, 3][0]; echo "foobar"[2]; 

 

支持爲負的字符串偏移量

如今全部接偏移量的內置的基於字符串的函數都支持接受負數做爲偏移量,包括數組解引用操做符([]).

var_dump("abcdef"[-2]); var_dump(strpos("aabbcc", "b", -3));

 

以上例程會輸出:

string (1) "e" int(3)

 

常量引用

「常量引用」意味着數組能夠直接操做字符串和數組字面值。舉兩個例子:

function randomHexString($length) { $str = ''; for ($i = 0; $i < $length; ++$i) { $str .= "0123456789abcdef"[mt_rand(0, 15)]; // direct dereference of string } } function randomBool() { return [false, true][mt_rand(0, 1)]; // direct dereference of array } 

 

常量加強

容許常量計算,容許使用包含數字、字符串字面值和常量的標量表達式

const A = 2; const B = A + 1; class C { const STR = "hello"; const STR2 = self::STR + ", world"; }

 

容許常量做爲函數參數默認

function test($arg = C::STR2)

 

類常量可見性 
如今起支持設置類常量的可見性。

class ConstDemo
{
    const PUBLIC_CONST_A = 1; public const PUBLIC_CONST_B = 2; protected const PROTECTED_CONST = 3; private const PRIVATE_CONST = 4; }

 

經過define()定義常量數組

define('ANIMALS', ['dog', 'cat', 'bird']); echo ANIMALS[1]; // outputs "cat"

 

函數變量類型聲明

兩種模式 : 強制 ( 默認 ) 和 嚴格模式 
類型:array,object(對象),string、int、float和 bool

class bar { function foo(bar $foo) { } //其中函數foo中的參數規定了傳入的參數必須爲bar類的實例,不然系統會判斷出錯。一樣對於數組來講,也能夠進行判斷,好比: function foo(array $foo) { } }   foo(array(1, 2, 3)); // 正確,由於傳入的是數組   foo(123); // 不正確,傳入的不是數組 function add(int $a) { return 1+$a; } var_dump(add(2)); function foo(int $i) { ... } foo(1); // $i = 1 foo(1.0); // $i = 1 foo("1"); // $i = 1 foo("1abc"); // not yet clear, maybe $i = 1 with notice foo(1.5); // not yet clear, maybe $i = 1 with notice foo([]); // error foo("abc"); // error 

 

參數跳躍

若是你有一個函數接受多個可選的參數,目前沒有辦法只改變最後一個參數,而讓其餘全部參數爲默認值。 
RFC上的例子,若是你有一個函數以下:

function create_query($where, $order_by, $join_type='', $execute = false, $report_errors = true) { ... } 

 

那麼有沒有辦法設置$report_errors=false,而其餘兩個爲默認值。爲了解決這個跳躍參數的問題而提出:

create_query("deleted=0", "name", default, default, false); 

 

可變函數參數

代替 func_get_args()

function add(...$args) { $result = 0; foreach($args as $arg) $result += $arg; return $result; } 

 

可爲空(Nullable)類型

類型如今容許爲空,當啓用這個特性時,傳入的參數或者函數返回的結果要麼是給定的類型,要麼是 null 。能夠經過在類型前面加上一個問號來使之成爲可爲空的。

function test(?string $name) { var_dump($name); }

以上例程會輸出:

string(5) "tpunt" NULL Uncaught Error: Too few arguments to function test(), 0 passed in...

 

Void 函數

在PHP 7 中引入的其餘返回值類型的基礎上,一個新的返回值類型void被引入。 返回值聲明爲 void 類型的方法要麼乾脆省去 return 語句,要麼使用一個空的 return 語句。 對於 void 函數來講,null 不是一個合法的返回值。

function swap(&$left, &$right) : void { if ($left === $right) { return; } $tmp = $left; $left = $right; $right = $tmp; } $a = 1; $b = 2; var_dump(swap($a, $b), $a, $b);

 

以上例程會輸出:

null int(2) int(1)

 

試圖去獲取一個 void 方法的返回值會獲得 null ,而且不會產生任何警告。這麼作的緣由是不想影響更高層次的方法。

返回值類型聲明

函數和匿名函數均可以指定返回值的類型

function show(): array { return [1,2,3,4]; } function arraysSum(array ...$arrays): array { return array_map(function(array $array): int { return array_sum($array); }, $arrays); }

參數解包功能

在調用函數的時候,經過 … 操做符能夠把數組或者可遍歷對象解包到參數列表,這和Ruby等語言中的擴張(splat)操做符相似

function add($a, $b, $c) { return $a + $b + $c; } $arr = [2, 3]; add(1, ...$arr);

 

實例化類

class test{ function show(){ return 'test'; } } echo (new test())->show();

 

支持 Class::{expr}() 語法

foreach ([new Human("Gonzalo"), new Human("Peter")] as $human) { echo $human->{'hello'}(); } 

Callable typehint

function foo(callable $callback) { }

 

foo("false"); //錯誤,由於false不是callable類型   foo("printf"); //正確   foo(function(){}); //正確 class A {   static function show() { } }   foo(array("A", "show")); //正確

 

Getter 和 Setter

若是你從不喜歡寫這些getXYZ()和setXYZ($value)方法,那麼這應該是你最受歡迎的改變。提議添加一個新的語法來定義一個屬性的設置/讀取:

class TimePeriod {  
    public $seconds; public $hours { get { return $this->seconds / 3600; } set { $this->seconds = $value * 3600; } } } $timePeriod = new TimePeriod; $timePeriod->hours = 10; var_dump($timePeriod->seconds); // int(36000) var_dump($timePeriod->hours); // int(10) 

 

迭代器 yield

目前,自定義迭代器不多使用,由於它們的實現,須要大量的樣板代碼。生成器解決這個問題,並提供了一種簡單的樣板代碼來建立迭代器。 
例如,你能夠定義一個範圍函數做爲迭代器:

function *xrange($start, $end, $step = 1) { for ($i = $start; $i < $end; $i += $step) { yield $i; } } foreach (xrange(10, 20) as $i) { // ... } 

 

上述xrange函數具備與內建函數相同的行爲,但有一點區別:不是返回一個數組的全部值,而是返回一個迭代器動態生成的值。

列表解析和生成器表達式

列表解析提供一個簡單的方法對數組進行小規模操做:

$firstNames = [foreach ($users as $user) yield $user->firstName]; 

上述列表解析相等於下面的代碼:

$firstNames = []; foreach ($users as $user) { $firstNames[] = $user->firstName; }

也能夠這樣過濾數組:

$underageUsers = [foreach ($users as $user) if ($user->age < 18) yield $user]; 

 

生成器表達式也很相似,可是返回一個迭代器(用於動態生成值)而不是一個數組。

生成器的返回值

在PHP5.5引入生成器的概念。生成器函數每執行一次就獲得一個yield標識的值。在PHP7中,當生成器迭代完成後,能夠獲取該生成器函數的返回值。經過Generator::getReturn()獲得。

function generator() { yield 1; yield 2; yield 3; return "a"; } $generatorClass = ("generator")(); foreach ($generatorClass as $val) { echo $val ." "; } echo $generatorClass->getReturn();

 

輸出爲:1 2 3 a

生成器中引入其餘生成器

在生成器中能夠引入另外一個或幾個生成器,只須要寫yield from functionName1

function generator1() { yield 1; yield 2; yield from generator2(); yield from generator3(); } function generator2() { yield 3; yield 4; } function generator3() { yield 5; yield 6; } foreach (generator1() as $val) { echo $val, " "; }

 

輸出:1 2 3 4 5 6

finally關鍵字

這個和Java中的finally同樣,經典的try … catch … finally 三段式異常處理。

多異常捕獲處理

一個catch語句塊如今能夠經過管道字符(|)來實現多個異常的捕獲。 這對於須要同時處理來自不一樣類的不一樣異常時頗有用。

try { // some code } catch (FirstException | SecondException $e) { // handle first and second exceptions } catch (\Exception $e) { // ... } finally{ // }

foreach 支持list()

對於「數組的數組」進行迭代,以前須要使用兩個foreach,如今只須要使用foreach + list了,可是這個數組的數組中的每一個數組的個數須要同樣。看文檔的例子一看就明白了。

$array = [ [1, 2], [3, 4], ]; foreach ($array as list($a, $b)) { echo "A: $a; B: $b\n"; } 

 

短數組語法 Symmetric array destructuring

短數組語法([])如今能夠用於將數組的值賦給一些變量(包括在foreach中)。 這種方式使從數組中提取值變得更爲容易。

$data = [ ['id' => 1, 'name' => 'Tom'], ['id' => 2, 'name' => 'Fred'], ]; while (['id' => $id, 'name' => $name] = $data) { // logic here with $id and $name }

 

list()如今支持鍵名

如今list()支持在它內部去指定鍵名。這意味着它能夠將任意類型的數組 都賦值給一些變量(與短數組語法相似)

$data = [ ['id' => 1, 'name' => 'Tom'], ['id' => 2, 'name' => 'Fred'], ]; while (list('id' => $id, 'name' => $name) = $data) { // logic here with $id and $name }

 

iterable 僞類

如今引入了一個新的被稱爲iterable的僞類 (與callable相似)。 這能夠被用在參數或者返回值類型中,它表明接受數組或者實現了Traversable接口的對象。 至於子類,當用做參數時,子類能夠收緊父類的iterable類型到array 或一個實現了Traversable的對象。對於返回值,子類能夠拓寬父類的 array或對象返回值類型到iterable。

function iterator(iterable $iter) { foreach ($iter as $val) { // } }

 

ext/openssl 支持 AEAD

經過給openssl_encrypt()和openssl_decrypt() 添加額外參數,如今支持了AEAD (模式 GCM and CCM)。 
經過 Closure::fromCallable() 將callables轉爲閉包 
Closure新增了一個靜態方法,用於將callable快速地 轉爲一個Closure 對象。

class Test { public function exposeFunction() { return Closure::fromCallable([$this, 'privateFunction']); } private function privateFunction($param) { var_dump($param); } } $privFunc = (new Test)->exposeFunction(); $privFunc('some value');

 

以上例程會輸出:

string(10) "some value"

匿名類

如今支持經過 new class 來實例化一個匿名類,這能夠用來替代一些「用後即焚」的完整類定義。

interface Logger { public function log(string $msg); } class Application { private $logger; public function getLogger(): Logger { return $this->logger; } public function setLogger(Logger $logger) { $this->logger = $logger; } } $app = new Application; $app->setLogger(new class implements Logger { public function log(string $msg) { echo $msg; } }); var_dump($app->getLogger());

Closure::call()

Closure::call() 如今有着更好的性能,簡短幹練的暫時綁定一個方法到對象上閉包並調用它。

class Test { public $name = "lixuan"; } //PHP7和PHP5.6均可以 $getNameFunc = function () { return $this->name; }; $name = $getNameFunc->bindTo(new Test, 'Test'); echo $name(); //PHP7能夠,PHP5.6報錯 $getX = function () { return $this->name; }; echo $getX->call(new Test);

爲unserialize()提供過濾

這個特性旨在提供更安全的方式解包不可靠的數據。它經過白名單的方式來防止潛在的代碼注入。

//將全部對象分爲__PHP_Incomplete_Class對象 $data = unserialize($foo, ["allowed_classes" => false]); //將全部對象分爲__PHP_Incomplete_Class 對象 除了ClassName1和ClassName2 $data = unserialize($foo, ["allowed_classes" => ["ClassName1", "ClassName2"]); //默認行爲,和 unserialize($foo)相同 $data = unserialize($foo, ["allowed_classes" => true]);

IntlChar

新增長的 IntlChar 類旨在暴露出更多的 ICU 功能。這個類自身定義了許多靜態方法用於操做多字符集的 unicode 字符。Intl是Pecl擴展,使用前須要編譯進PHP中,也可apt-get/yum/port install php5-intl

printf('%x', IntlChar::CODEPOINT_MAX); echo IntlChar::charName('@'); var_dump(IntlChar::ispunct('!'));

以上例程會輸出: 
10ffff 
COMMERCIAL AT 
bool(true)

預期

預期是向後兼用並加強以前的 assert() 的方法。 它使得在生產環境中啓用斷言爲零成本,而且提供當斷言失敗時拋出特定異常的能力。 老版本的API出於兼容目的將繼續被維護,assert()如今是一個語言結構,它容許第一個參數是一個表達式,而不只僅是一個待計算的 string或一個待測試的boolean。

ini_set('assert.exception', 1); class CustomError extends AssertionError {} assert(false, new CustomError('Some error message'));

以上例程會輸出: 
Fatal error: Uncaught CustomError: Some error message

intdiv()

接收兩個參數做爲被除數和除數,返回他們相除結果的整數部分。

var_dump(intdiv(7, 2));

輸出int(3)

CSPRNG

新增兩個函數: random_bytes() and random_int().能夠加密的生產被保護的整數和字符串。總之隨機數變得安全了。 
random_bytes — 加密生存被保護的僞隨機字符串 
random_int —加密生存被保護的僞隨機整數

preg_replace_callback_array()

新增了一個函數preg_replace_callback_array(),使用該函數可使得在使用preg_replace_callback()函數時代碼變得更加優雅。在PHP7以前,回調函數會調用每個正則表達式,回調函數在部分分支上是被污染了。

Session options

如今,session_start()函數能夠接收一個數組做爲參數,能夠覆蓋php.ini中session的配置項。 
好比,把cache_limiter設置爲私有的,同時在閱讀完session後當即關閉。

session_start(['cache_limiter' => 'private', 'read_and_close' => true, ]);

$_SERVER[「REQUEST_TIME_FLOAT」]

這個是用來統計服務請求時間的,並用ms(毫秒)來表示

echo "腳本執行時間 ", round(microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"], 2), "s"; 

empty() 支持任意表達式

empty() 如今支持傳入一個任意表達式,而不只是一個變量

function always_false() { return false; } if (empty(always_false())) { echo 'This will be printed.'; } if (empty(true)) { echo 'This will not be printed.'; }

輸出 
This will be printed.

php://input 能夠被複用

php://input 開始支持屢次打開和讀取,這給處理POST數據的模塊的內存佔用帶來了極大的改善。

Upload progress 文件上傳

Session提供了上傳進度支持,經過$_SESSION[「upload_progress_name」]就能夠得到當前文件上傳的進度信息,結合Ajax就能很容易實現上傳進度條了。 
詳細的看http://www.laruence.com/2011/10/10/2217.html

大文件上傳支持

能夠上傳超過2G的大文件。

GMP支持操做符重載

GMP 對象支持操做符重載和轉換爲標量,改善了代碼的可讀性,如:

$a = gmp_init(42); $b = gmp_init(17); // Pre-5.6 code: var_dump(gmp_add($a, $b)); var_dump(gmp_add($a, 17)); var_dump(gmp_add(42, $b)); // New code: var_dump($a + $b); var_dump($a + 17); var_dump(42 + $b); 

JSON 序列化對象

實現了JsonSerializable接口的類的實例在json_encode序列化的以前會調用jsonSerialize方法,而不是直接序列化對象的屬性。 
參考http://www.laruence.com/2011/10/10/2204.html

HTTP狀態碼在200-399範圍內均被認爲訪問成功

支持動態調用靜態方法

class Test{ public static function testgo() { echo "gogo!"; } } $class = 'Test'; $action = 'testgo'; $class::$action(); //輸出 "gogo!"

棄用e修飾符

e修飾符是指示preg_replace函數用來評估替換字符串做爲PHP代碼,而不僅是僅僅作一個簡單的字符串替換。不出所料,這種行爲會源源不斷的出現安全問題。這就是爲何在PHP5.5 中使用這個修飾符將拋出一個棄用警告。做爲替代,你應該使用preg_replace_callback函數。你能夠從RFC找到更多關於這個變化相應的信息。

新增函數 boolval

PHP已經實現了strval、intval和floatval的函數。爲了達到一致性將添加boolval函數。它徹底能夠做爲一個布爾值計算,也能夠做爲一個回調函數。

新增函數hash_pbkdf2

PBKDF2全稱「Password-Based Key Derivation Function 2」,正如它的名字同樣,是一種從密碼派生出加密密鑰的算法。這就須要加密算法,也能夠用於對密碼哈希。更普遍的說明和用法示例

array_column

//從數據庫獲取一列,但返回是數組。 $userNames = []; foreach ($users as $user) { $userNames[] = $user['name']; } //之前獲取數組某列值,如今以下 $userNames = array_column($users, 'name'); 

一個簡單的密碼散列API

$password = "foo"; // creating the hash $hash = password_hash($password, PASSWORD_BCRYPT); // verifying a password if (password_verify($password, $hash)) { // password correct! } else { // password wrong! } 

異步信號處理 Asynchronous signal handling

A new function called pcntl_async_signals() has been introduced to enable asynchronous signal handling without using ticks (which introduce a lot of overhead). 
增長了一個新函數 pcntl_async_signals()來處理異步信號,不須要再使用ticks(它會增長佔用資源)

pcntl_async_signals(true); // turn on async signals pcntl_signal(SIGHUP, function($sig) { echo "SIGHUP\n"; }); posix_kill(posix_getpid(), SIGHUP);

 

以上例程會輸出:

SIGHUP

HTTP/2 服務器推送支持 ext/curl

Support for server push has been added to the CURL extension (requires version 7.46 and above). This can be leveraged through the curl_multi_setopt() function with the new CURLMOPT_PUSHFUNCTION constant. The constants CURL_PUST_OK and CURL_PUSH_DENY have also been added so that the execution of the server push callback can either be approved or denied. 
蹩腳英語: 
對於服務器推送支持添加到curl擴展(須要7.46及以上版本)。 
能夠經過用新的CURLMOPT_PUSHFUNCTION常量 讓curl_multi_setopt()函數使用。 
也增長了常量CURL_PUST_OK和CURL_PUSH_DENY,能夠批准或拒絕 服務器推送回調的執行

php.ini中可以使用變量

PHP default_charset 默認字符集 爲UTF-8

ext/phar、ext/intl、ext/fileinfo、ext/sqlite3和ext/enchant等擴展默認隨PHP綁定發佈。其中Phar可用於打包PHP程序,相似於Java中的jar機制

PHP7.1不兼容性

1.當傳遞參數過少時將拋出錯誤

在過去若是咱們調用一個用戶定義的函數時,提供的參數不足,那麼將會產生一個警告(warning)。 如今,這個警告被提高爲一個錯誤異常(Error exception)。這個變動僅對用戶定義的函數生效, 並不包含內置函數。例如:

function test($param){} test();

 

輸出:

Uncaught Error: Too few arguments to function test(), 0 passed in %s on line %d and exactly 1 expected in %s:%d

 

2.禁止動態調用函數

禁止動態調用函數以下 
assert() - with a string as the first argument 
compact() 
extract() 
func_get_args() 
func_get_arg() 
func_num_args() 
get_defined_vars() 
mb_parse_str() - with one arg 
parse_str() - with one arg

(function () { 'func_num_args'(); })();

 

輸出

Warning: Cannot call func_num_args() dynamically in %s on line %d

 

3.無效的類,接口,trait名稱命名

如下名稱不能用於 類,接口或trait 名稱命名: 
void 
iterable

4.Numerical string conversions now respect scientific notation

Integer operations and conversions on numerical strings now respect scientific notation. This also includes the (int) cast operation, and the following functions: intval() (where the base is 10), settype(), decbin(), decoct(), and dechex().

5.mt_rand 算法修復

mt_rand() will now default to using the fixed version of the Mersenne Twister algorithm. If deterministic output from mt_srand() was relied upon, then the MT_RAND_PHP with the ability to preserve the old (incorrect) implementation via an additional optional second parameter to mt_srand().

6.rand() 別名 mt_rand() 和 srand() 別名 mt_srand()

rand() and srand() have now been made aliases to mt_rand() and mt_srand(), respectively. This means that the output for the following functions have changes: rand(), shuffle(), str_shuffle(), and array_rand().

7.Disallow the ASCII delete control character in identifiers

The ASCII delete control character (0x7F) can no longer be used in identifiers that are not quoted.

8.error_log changes with syslog value

If the error_log ini setting is set to syslog, the PHP error levels are mapped to the syslog error levels. This brings finer differentiation in the error logs in contrary to the previous approach where all the errors are logged with the notice level only.

9.在不完整的對象上再也不調用析構方法

析構方法在一個不完整的對象(例如在構造方法中拋出一個異常)上將再也不會被調用

10.call_user_func()再也不支持對傳址的函數的調用

call_user_func() 如今在調用一個以引用做爲參數的函數時將始終失敗。

11.字符串再也不支持空索引操做符 The empty index operator is not supported for strings anymore

對字符串使用一個空索引操做符(例如str[]=x)將會拋出一個致命錯誤, 而不是靜默地將其轉爲一個數組

12.ini配置項移除

下列ini配置項已經被移除: 
session.entropy_file 
session.entropy_length 
session.hash_function 
session.hash_bits_per_character

PHP7.0 不兼容性

一、foreach再也不改變內部數組指針

在PHP7以前,當數組經過 foreach 迭代時,數組指針會移動。如今開始,再也不如此,見下面代碼。

$array = [0, 1, 2]; foreach ($array as &$val) { var_dump(current($array)); }

PHP5輸出: 
int(1) 
int(2) 
bool(false) 
PHP7輸出: 
int(0) 
int(0) 
int(0)

二、foreach經過引用遍歷時,有更好的迭代特性

當使用引用遍歷數組時,如今 foreach 在迭代中能更好的跟蹤變化。例如,在迭代中添加一個迭代值到數組中,參考下面的代碼:

$array = [0]; foreach ($array as &$val) { var_dump($val); $array[1] = 1; }

PHP5輸出: 
int(0) 
PHP7輸出: 
int(0) 
int(1)

三、十六進制字符串再也不被認爲是數字

含十六進制字符串再也不被認爲是數字

var_dump("0x123" == "291"); var_dump(is_numeric("0x123")); var_dump("0xe" + "0x1"); var_dump(substr("foo", "0x1"));

PHP5輸出: 
bool(true) 
bool(true) 
int(15) 
string(2) 「oo」 
PHP7輸出: 
bool(false) 
bool(false) 
int(0) 
Notice: A non well formed numeric value encountered in /tmp/test.php on line 5 
string(3) 「foo」

四、PHP7中被移除的函數

被移除的函數列表以下: 
call_user_func() 和 call_user_func_array()從PHP 4.1.0開始被廢棄。 
已廢棄的 mcrypt_generic_end() 函數已被移除,請使用mcrypt_generic_deinit()代替。 
已廢棄的 mcrypt_ecb(), mcrypt_cbc(), mcrypt_cfb() 和 mcrypt_ofb() 函數已被移除。 
set_magic_quotes_runtime(), 和它的別名 magic_quotes_runtime()已被移除. 它們在PHP 5.3.0中已經被廢棄,而且 在in PHP 5.4.0也因爲魔術引號的廢棄而失去功能。 
已廢棄的 set_socket_blocking() 函數已被移除,請使用stream_set_blocking()代替。 
dl()在 PHP-FPM 再也不可用,在 CLI 和 embed SAPIs 中仍可用。 
GD庫中下列函數被移除:imagepsbbox()、imagepsencodefont()、imagepsextendfont()、imagepsfreefont()、imagepsloadfont()、imagepsslantfont()、imagepstext() 
在配置文件php.ini中,always_populate_raw_post_data、asp_tags、xsl.security_prefs被移除了。

五、new 操做符建立的對象不能以引用方式賦值給變量

new 操做符建立的對象不能以引用方式賦值給變量

class C {} $c =& new C;

PHP5輸出: 
Deprecated: Assigning the return value of new by reference is deprecated in /tmp/test.php on line 3 
PHP7輸出: 
Parse error: syntax error, unexpected ‘new’ (T_NEW) in /tmp/test.php on line 3

六、移除了 ASP 和 script PHP 標籤

使用相似 ASP 的標籤,以及 script 標籤來區分 PHP 代碼的方式被移除。 受到影響的標籤有:<% %>、<%= %>、

七、從不匹配的上下文發起調用

在不匹配的上下文中以靜態方式調用非靜態方法, 在 PHP 5.6 中已經廢棄, 可是在 PHP 7.0 中, 會致使被調用方法中未定義 $this 變量,以及此行爲已經廢棄的警告。

class A { public function test() { var_dump($this); } } // 注意:並無從類 A 繼承 class B { public function callNonStaticMethodOfA() { A::test(); } } (new B)->callNonStaticMethodOfA();

PHP5輸出: 
Deprecated: Non-static method A::test() should not be called statically, assuming $this from incompatible context in /tmp/test.php on line 8 
object(B)#1 (0) { 

PHP7輸出: 
Deprecated: Non-static method A::test() should not be called statically in /tmp/test.php on line 8 
Notice: Undefined variable: this in /tmp/test.php on line 3 
NULL

八、在數值溢出的時候,內部函數將會失敗

將浮點數轉換爲整數的時候,若是浮點數值太大,致使沒法以整數表達的狀況下, 在以前的版本中,內部函數會直接將整數截斷,並不會引起錯誤。 在 PHP 7.0 中,若是發生這種狀況,會引起 E_WARNING 錯誤,而且返回 NULL。

九、JSON 擴展已經被 JSOND 取代

JSON 擴展已經被 JSOND 擴展取代。 
對於數值的處理,有如下兩點須要注意的: 
第一,數值不能以點號(.)結束 (例如,數值 34. 必須寫做 34.0 或 34)。 
第二,若是使用科學計數法表示數值,e 前面必須不是點號(.) (例如,3.e3 必須寫做 3.0e3 或 3e3)。

十、INI 文件中 # 註釋格式被移除

在配置文件INI文件中,再也不支持以 # 開始的註釋行, 請使用 ;(分號)來表示註釋。 此變動適用於 php.ini 以及用 parse_ini_file() 和 parse_ini_string() 函數來處理的文件。

十一、$HTTP_RAW_POST_DATA 被移除

再也不提供 $HTTP_RAW_POST_DATA 變量。 請使用 php://input 做爲替代。

十二、yield 變動爲右聯接運算符

在使用 yield 關鍵字的時候,再也不須要括號, 而且它變動爲右聯接操做符,其運算符優先級介於 print 和 => 之間。 這可能致使現有代碼的行爲發生改變。能夠經過使用括號來消除歧義。

echo yield -1; // 在以前版本中會被解釋爲: echo (yield) - 1; // 如今,它將被解釋爲: echo yield (-1); yield $foo or die; // 在以前版本中會被解釋爲: yield ($foo or die); // 如今,它將被解釋爲: (yield $foo) or die;

PHP 7.1.x 中廢棄的特性

1.ext/mcrypt

mcrypt 擴展已通過時了大約10年,而且用起來很複雜。所以它被廢棄而且被 OpenSSL 所取代。 從PHP 7.2起它將被從核心代碼中移除而且移到PECL中。

2.mb_ereg_replace()和mb_eregi_replace()的Eval選項

對於mb_ereg_replace()和mb_eregi_replace()的 e模式修飾符如今已被廢棄

棄用或廢除

下面是被棄用或廢除的 INI 指令列表. 使用下面任何指令都將致使 錯誤. 
define_syslog_variables 
register_globals 
register_long_arrays 
safe_mode 
magic_quotes_gpc 
magic_quotes_runtime 
magic_quotes_sybase 
棄用 INI 文件中以 ‘#’ 開頭的註釋. 
棄用函數: 
call_user_method() (使用 call_user_func() 替代) 
call_user_method_array() (使用 call_user_func_array() 替代) 
define_syslog_variables() 
dl() 
ereg() (使用 preg_match() 替代) 
ereg_replace() (使用 preg_replace() 替代) 
eregi() (使用 preg_match() 配合 ‘i’ 修正符替代) 
eregi_replace() (使用 preg_replace() 配合 ‘i’ 修正符替代) 
set_magic_quotes_runtime() 以及它的別名函數 magic_quotes_runtime() 
session_register() (使用 SESSION)sessionunregister()(使_SESSION 超所有變量替代) session_is_registered() (使用 $_SESSION 超所有變量替代) set_socket_blocking() (使用 stream_set_blocking() 替代) split() (使用 preg_split() 替代) spliti() (使用 preg_split() 配合 ‘i’ 修正符替代) sql_regcase() mysql_db_query() (使用 mysql_select_db() 和 mysql_query() 替代) mysql_escape_string() (使用 mysql_real_escape_string() 替代) 廢棄以字符串傳遞區域設置名稱. 使用 LC_* 系列常量替代. mktime() 的 is_dst 參數. 使用新的時區處理函數替代. 棄用的功能: 棄用經過引用分配 new 的返回值. 調用時傳遞引用被棄用. 已棄用的多個特性 allow_call_time_pass_reference、define_syslog_variables、highlight.bg、register_globals、register_long_arrays、magic_quotes、safe_mode、zend.ze1_compatibility_mode、session.bug_compat4二、session.bug_compat_warn 以及 y2k_compliance。

相關文章
相關標籤/搜索