<?php
function swap( &$a, &$b ): void
{ [ $a, $b ] = [ $b, $a ]; }
?>
パラメータや戻り値の型宣言で nullable 指定ができるようになりました。
型の前にクエスチョンマークをつけると、nullable であることを指定できます。
nullable 指定をすると、指定した型だけでなく null
も渡せるようになります。
<?php
function testReturn(): ?string
{
return 'elePHPant';
}
var_dump(testReturn());
function testReturn(): ?string
{
return null;
}
var_dump(testReturn());
function test(?string $name)
{
var_dump($name);
}
test('elePHPant');
test(null);
test();
上の例の出力は以下となります。
string(10) "elePHPant" NULL string(10) "elePHPant" NULL Uncaught Error: Too few arguments to function test(), 0 passed in...
戻り値の型として void が導入されました。戻り値の型を void
と宣言した関数は、関数内での return 文を省略するか、あるいは空の return を使う必要があります。
void 関数から null
を返すことはできません。
<?php
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
と評価されます。
警告は発生しません。警告を発生させると、一般的な高階関数の利用にも影響するからです。
配列の短縮構文 ([]
) を使って、
代入用に配列の値を取り出せるようになりました (foreach
でも使えます)。
これは、list() の代替として使えます
(list() もまだ使えます)。
<?php
$data = [
[1, 'Tom'],
[2, 'Fred'],
];
// list() 形式
list($id1, $name1) = $data[0];
// [] 形式
[$id1, $name1] = $data[0];
// list() 形式
foreach ($data as list($id, $name)) {
// $id と $name を使う処理をここに書きます
}
// [] 形式
foreach ($data as [$id, $name]) {
// $id と $name を使う処理をここに書きます
}
クラス定数のアクセス範囲を指定できるようになりました。
<?php
class ConstDemo
{
const PUBLIC_CONST_A = 1;
public const PUBLIC_CONST_B = 2;
protected const PROTECTED_CONST = 3;
private const PRIVATE_CONST = 4;
}
新しい擬似型 (callable と同じような型) である iterable が導入されました。 パラメータおよび戻り値の型指定で使うことができます。 配列か、あるいは Traversable インターフェイスを実装したオブジェクトを受け付けるようになります。 派生型に貸しては、子クラスのパラメータの型が、 親クラスの array や Traversable を拡張して iterable に広げることができます。 戻り値の型に関しては、親クラスの iterable 型指定を子クラスで 配列あるいはオブジェクト (Traversable を実装したもの) に絞り込むことができます。
<?php
function iterator(iterable $iter)
{
foreach ($iter as $val) {
//
}
}
ひとつの catch ブロックで複数の例外を扱えるようになりました。
パイプ文字 (|
) を使って指定します。
これは、異なるクラス階層に由来する異なる例外を同じように処理したい場合に有用です。
<?php
try {
// 何かのコード
} catch (FirstException | SecondException $e) {
// FirstException と SecondException をこのブロックで処理します
}
list() (あるいはその短縮版である []
構文)
の内部でキーを指定できるようになりました。
つまり、キーが整数でなかったりシーケンシャルでなかったりした場合でも、
配列の値を取り出せるようになったということです。
<?php
$data = [
["id" => 1, "name" => 'Tom'],
["id" => 2, "name" => 'Fred'],
];
// list() 形式
list("id" => $id1, "name" => $name1) = $data[0];
// [] 形式
["id" => $id1, "name" => $name1] = $data[0];
// list() 形式
foreach ($data as list("id" => $id, "name" => $name)) {
// $id と $name を使う処理をここに書きます
}
// [] 形式
foreach ($data as ["id" => $id, "name" => $name]) {
// $id と $name を使う処理をここに書きます
}
文字列操作関数
のうちオフセット指定のできるものすべてについて、負のオフセットを指定できるようになりました。
[]
や {}
による
文字列への文字単位のアクセス
についても同様です。
負のオフセットは、文字列の末尾からのオフセットと解釈されます。
<?php
var_dump("abcdef"[-2]);
var_dump(strpos("aabbcc", "b", -3));
上の例の出力は以下となります。
string (1) "e" int(3)
文字列や配列に対する負のオフセットが、文字列内での単純な変数パース構文においても使えるようになりました。
<?php
$string = 'bar';
echo "The last character of '$string' is '$string[-1]'.\n";
?>
上の例の出力は以下となります。
The last character of 'bar' is 'r'.
openssl_encrypt() および openssl_decrypt() の追加のパラメータで、 AEAD (GCM モードおよび CCM モード) をサポートするようになりました。
Closure クラスに新しいstaticメソッドが追加されました。 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');
上の例の出力は以下となります。
string(10) "some value"
新しい関数 pcntl_async_signals() が追加されました。これは、tick を使わない非同期シグナルハンドリングを有効にするものです (tick は相当大きなオーバーヘッドになります)。
<?php
pcntl_async_signals(true); // 非同期シグナルを有効にします
pcntl_signal(SIGHUP, function($sig) {
echo "SIGHUP\n";
});
posix_kill(posix_getpid(), SIGHUP);
上の例の出力は以下となります。
SIGHUP
CURL 拡張モジュールがサーバープッシュに対応するようになりました
(curl バージョン 7.46 以降が必要です)。
curl_multi_setopt() 関数に新しい定数
CURLMOPT_PUSHFUNCTION
を指定すれば、この機能を使えます。
また、定数
CURL_PUSH_OK
と CURL_PUSH_DENY
も新たに追加されました。
これらは、サーバープッシュコールバックの実行を許可したり拒否したりするものです。
tcp_nodelay ストリームコンテキストオプションが追加されました。
Note that declaring nullable return type does not mean that you can skip return statement at all. For example:
php > function a(): ?string { }
php > a();
PHP Warning: Uncaught TypeError: Return value of a() must be of the type string or null, none returned in php shell code:2
php > function b(): ?string { return; }
PHP Fatal error: A function with return type must return a value (did you mean "return null;" instead of "return;"?) in php shell code on line 2