標(biāo)量類(lèi)型聲明有兩種模式:強(qiáng)制(默認(rèn))模式、嚴(yán)格模式。下列參數(shù)類(lèi)型可以使用(無(wú)論用強(qiáng)制模式還是嚴(yán)格模式):字符串(string)、整形(int)、浮點(diǎn)數(shù)(float)和布爾型(bool)。其他類(lèi)型在 PHP5 中有支持:類(lèi)名、接口、數(shù)組和可被調(diào)用的。
<?php
// Coercive mode
function sumOfInts(int ...$ints)
{
return array_sum($ints);
}
var_dump(sumOfInts(2, '3', 4.1));
上述例子輸出:
int(9)
當(dāng)開(kāi)啟嚴(yán)格模式后,一個(gè)?declare?聲明必須置于 PHP 腳本文件開(kāi)頭,這意味著嚴(yán)格聲明標(biāo)量是基于文件可配的。這個(gè)指令不僅影響參數(shù)的類(lèi)型聲明,也影響到函數(shù)的返回值聲明(詳見(jiàn)下面的返回值聲明)。
詳細(xì)的標(biāo)量類(lèi)型聲明的文檔與示例,可以查看類(lèi)型聲明頁(yè)面。
PHP7 新增了返回類(lèi)型聲明,類(lèi)似于參數(shù)類(lèi)型聲明,返回類(lèi)型聲明提前聲明了函數(shù)返回值的類(lèi)型??捎玫穆暶黝?lèi)型與參數(shù)聲明中可用的類(lèi)型相同。
<?php
function arraysSum(array ...$arrays): array
{
return array_map(function(array $array): int {
return array_sum($array);
}, $arrays);
}
print_r(arraysSum([1,2,3], [4,5,6], [7,8,9]));
上述代碼返回值為:
Array
(
[0] => 6
[1] => 15
[2] => 24
)
詳細(xì)的返回值聲明相關(guān)的文檔和示例代碼可以查閱返回值聲明文檔。
空合并算子的操作符為???
?,已經(jīng)作為一種語(yǔ)法糖用于日常需求中用于三元表達(dá)式,它與 isset() 同時(shí)發(fā)生。如果變量存在且不為空,它就會(huì)返回對(duì)應(yīng)的值,相反,它返回它的第二個(gè)操作數(shù)。
<?php
// Fetches the value of $_GET['user'] and returns 'nobody'
// if it does not exist.
$username = $_GET['user'] ?? 'nobody';
// This is equivalent to:
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
// Coalesces can be chained: this will return the first
// defined value out of $_GET['user'], $_POST['user'], and
// 'nobody'.
$username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';
?>
太空船操作符用于比較兩個(gè)表達(dá)式。它返回一個(gè)大于 0、等于 0、小于 0 的數(shù),用于表示 $a 與 $b 之間的關(guān)系。比較的原則是沿用 PHP 的常規(guī)比較規(guī)則進(jìn)行的。
<?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
?>
Array 類(lèi)型的常量可以通過(guò) define() 來(lái)定義。在 PHP5.6 中僅能通過(guò) const 定義。
<?php
define('ANIMALS', [
'dog',
'cat',
'bird'
]);
echo ANIMALS[1]; // outputs "cat"
?>
可以通過(guò) new 關(guān)鍵字初始化一個(gè)匿名類(lèi)。匿名類(lèi)使用場(chǎng)景與完整的類(lèi)場(chǎng)景相同。
<?php
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());
?>
上面代碼輸出:
object(class@anonymous)#2 (0) {
}
詳細(xì)文檔可以參考匿名類(lèi)文檔
通過(guò)十六進(jìn)制內(nèi)容與雙引號(hào)組成的字符串生成 Unicode codepoint,可以接受任何有效的 codepoint,并且開(kāi)頭的 0 是可以省略的。
echo "\u{aa}";
echo "\u{0000aa}";
echo "\u{9999}";
上面代碼輸出:
(same as before but with optional leading 0's)
閉包?Closure::call()?有著更好的性能,簡(jiǎn)短干練的暫時(shí)綁定一個(gè)方法到對(duì)象上閉包并調(diào)用它。
<?php
class A {private $x = 1;}
// Pre PHP 7 code
$getXCB = function() {return $this->x;};
$getX = $getXCB->bindTo(new A, 'A'); // intermediate closure
echo $getX();
// PHP 7+ code
$getX = function() {return $this->x;};
echo $getX->call(new A);
上述代碼輸出:
1
1
這個(gè)特性意在提供更安全的方式解包不可靠的數(shù)據(jù)。通過(guò)白名單的方式來(lái)防止代碼注入。
<?php
// converts all objects into __PHP_Incomplete_Class object
$data = unserialize($foo, ["allowed_classes" => false]);
// converts all objects into __PHP_Incomplete_Class object except those of MyClass and MyClass2
$data = unserialize($foo, ["allowed_classes" => ["MyClass", "MyClass2"]);
// default behaviour (same as omitting the second argument) that accepts all classes
$data = unserialize($foo, ["allowed_classes" => true]);
新增加的 IntlChar 類(lèi)意在于暴露出更多的 ICU 功能。類(lèi)自身定義了許多靜態(tài)方法用于操作 unicode 字符。
<?php
printf('%x', IntlChar::CODEPOINT_MAX);
echo IntlChar::charName('@');
var_dump(IntlChar::ispunct('!'));
上述代碼輸出:
10ffff
COMMERCIAL AT
bool(true)
若要使用此類(lèi),請(qǐng)先安裝Intl擴(kuò)展。
預(yù)期(增強(qiáng)的斷言)是向后兼用以增強(qiáng) assert() 方法。在代碼中啟用斷言為零成本,并且提供拋出特定異常的能力。
在使用老版本 API 時(shí),如果第一個(gè)參數(shù)是一個(gè)字符串,那么它將被解析。第二個(gè)參數(shù)可以是一個(gè)簡(jiǎn)單的字符串(導(dǎo)致 AssertionError 被觸發(fā)),或一個(gè)包含一個(gè)錯(cuò)誤消息的自定義異常對(duì)象。
<?php
ini_set('assert.exception', 1);
class CustomError extends AssertionError {}
assert(false, new CustomError('Some error message'));
上述代碼輸出:
Fatal error: Uncaught CustomError: Some error message
這個(gè)特性會(huì)帶來(lái)兩個(gè) PHP.ini 設(shè)置(以及它們的默認(rèn)值):
zend.assertions 有三種值:
assert.exception 意味著斷言失敗時(shí)拋出異常。默認(rèn)關(guān)閉保持兼容舊的 assert() 函數(shù)。
在 PHP7 之前需要聲明一大堆命名空間,但是現(xiàn)在可以通過(guò) use 的新特性,批量聲明。
<?php
// Pre PHP 7 code
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;
// PHP 7+ code
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};
This feature builds upon the generator functionality introduced into PHP 5.5. It enables for a return statement to be used within a generator to enable for a final expression to be returned (return by reference is not allowed). This value can be fetched using the new Generator::getReturn() method, which may only be used once the generator has finishing yielding values.
<?php
$gen = (function() {
yield 1;
yield 2;
return 3;
})();
foreach ($gen as $val) {
echo $val, PHP_EOL;
}
echo $gen->getReturn(), PHP_EOL;
上述代碼輸出:
1
2
3
Being able to explicitly return a final value from a generator is a handy ability to have. This is because it enables for a final value to be returned by a generator (from perhaps some form of coroutine computation) that can be specifically handled by the client code executing the generator. This is far simpler than forcing the client code to firstly check whether the final value has been yielded, and then if so, to handle that value specifically.
Generator delegation builds upon the ability of being able to return expressions from generators. It does this by using an new syntax of yield from , where can be any Traversable object or array. This will be advanced until no longer valid, and then execution will continue in the calling generator. This feature enables yield statements to be broken down into smaller operations, thereby promoting cleaner code that has greater reusability.
<?php
function gen()
{
yield 1;
yield 2;
return yield from gen2();
}
function gen2()
{
yield 3;
return 4;
}
$gen = gen();
foreach ($gen as $val)
{
echo $val, PHP_EOL;
}
echo $gen->getReturn();
上述代碼輸出:
1
2
3
4
intdiv() 函數(shù)來(lái)處理整除,并返回一個(gè)整數(shù)。
<?php
var_dump(intdiv(10, 3));
上述代碼輸出:
int(3)
該特性給 session_start() 函數(shù)提供一些設(shè)置能力,當(dāng)然這些設(shè)置可以在 PHP.ini 中設(shè)置。
<?php
session_start(['cache_limiter' => 'private']); // sets the session.cache_limiter option to private
這個(gè)特性還引入了一個(gè)新的 php.ini 設(shè)置( session.lazy_write ),默認(rèn)情況下為 true,表示改變會(huì)話數(shù)據(jù)只是重寫(xiě)。
這個(gè)新功能,當(dāng)你使用 preg_replace_callback() 函數(shù)時(shí)代碼更清晰可讀。在PHP7之前,每個(gè)正則表達(dá)式都需要回調(diào)( preg_replace_callback() 函數(shù)的第二個(gè)參數(shù) )中來(lái)實(shí)現(xiàn)功能,這會(huì)使流程混亂不可控。
現(xiàn)在,回調(diào)可以通過(guò)與正則表達(dá)式綁定著寫(xiě),只需將正則表達(dá)式作為 key,回調(diào)函數(shù)作為 value。
<?php
$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
);
該特性涵蓋兩個(gè)函數(shù),用于生成安全的整形與字符串,主要用于密碼場(chǎng)景。它提供了簡(jiǎn)單的 API 和平臺(tái)無(wú)關(guān)性。
string random_bytes(int length);
int random_int(int min, int max);
兩個(gè)函數(shù)在沒(méi)有足夠的隨機(jī)性時(shí)會(huì)報(bào) E_WARNING 錯(cuò)誤并且返回 false。
更多建議: