スカラー
型宣言
には二つの方式があります。デフォルトの自動変換(coercive) モードと、
厳密に判断する strict モードです。
パラメータとして、
文字列 (string)、整数 (int
)、浮動小数点数
(float)、boolean (bool
)
といった型をいずれかの方式で強制できるようになりました。
これらは、PHP 5 で導入された型宣言 (クラス名やインターフェイス、配列そして callable)
を強化するものです。
<?php
// デフォルトのモード
function sumOfInts(int ...$ints)
{
return array_sum($ints);
}
var_dump(sumOfInts(2, '3', 4.1));
上の例の出力は以下となります。
int(9)
strict モードを有効にするには、ファイルの先頭に declare
ディレクティブを置く必要があります。
つまり、スカラー型を厳密に扱うかどうかは、ファイル単位で定めるということです。
このディレクティブは、パラメータの型宣言だけでなく、関数の戻り値の型
(戻り値の型宣言を参照ください)
や PHP の標準関数、そして拡張モジュールの関数にも影響を及ぼします。
スカラー型宣言に関するドキュメントやサンプルについては、 型宣言 を参照ください。
PHP 7 では、 戻り値の型宣言 もできるようになりました。 引数の型宣言 と同様に、戻り値の型宣言では、関数が戻す値がどの型になるかを宣言します。 戻り値の型宣言で使える 型 は、引数の型宣言で使えるものと同じです。
<?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 )
詳細なドキュメントやサンプルについては、 戻り値の型宣言. を参照ください。
null 合体演算子 (??
) がシンタックスシュガーとして追加されました。
三項演算子と isset() を組み合わせる
よくありがちなパターンを、より簡単に書くためのものです。
この演算子は、もし第一オペランドが非 null
の値であればそれを返し、
そうでない場合は第二オペランドを返します。
<?php
// $_GET['user'] を取得します。もし存在しない場合は
// 'nobody' を用います。
$username = $_GET['user'] ?? 'nobody';
// 上のコードは、次のコードと同じ意味です。
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
// 合体演算子を連結することもできます。次のように書くと、
// $_GET['user']、$_POST['user'] そして 'nobody'
// の順に調べて、非 &null; が定義されている最初の値を返します。
$username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';
?>
宇宙船演算子は、二つの式を比較するために使うものです。 $a が $b より大きい場合は 1、 $a と $b が等しい場合は 0、 $a が $b より小さい場合は -1 をそれぞれ返します。 比較の際には、 PHP 型の比較表 のルールを用います。
<?php
// 整数値
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1
// 浮動小数点数値
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1
// 文字列
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1
?>
define() で配列の定数を定義できるようになりました。
PHP 5.6 までのバージョンでは、配列の定数は const
でしか定義できませんでした。
<?php
define('ANIMALS', [
'dog',
'cat',
'bird'
]);
echo ANIMALS[1]; // "cat" と出力します
?>
無名クラスをサポートするようになりました。new
class
を使って利用します。
その場限りの使い捨てのオブジェクトなどで、完全なクラス定義のかわりとして使えます。
<?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) { }
詳細なドキュメントは 無名クラス を参照ください。
Unicode のコードポイントを十六進形式で受け取って、 それを UTF-8 で (ダブルクォートで囲まれた文字列あるいはヒアドキュメントとして) 出力します。 妥当な形式のコードポイントならあらゆるものが使えます。先頭のゼロは省略してもかまいません。
echo "\u{aa}";
echo "\u{0000aa}";
echo "\u{9999}";
上の例の出力は以下となります。
a a (先頭のゼロを省略せずに書いても、前の行と同じ結果になります) 香
Closure::call() は、オブジェクトのスコープをクロージャに一時的に束縛して実行するための、 より高性能で簡潔な方法です。
<?php
class A {private $x = 1;}
// 以前のバージョンのコード
$getX = function() {return $this->x;};
$getXCB = $getX->bindTo(new A, 'A'); // 中間クロージャが必要
echo $getXCB();
// PHP 7 以降でのコード
$getX = function() {return $this->x;};
echo $getX->call(new A);
上の例の出力は以下となります。
1 1
この仕組みは、信頼できないデータからオブジェクトを復元する際に、 よりセキュリティを高められるようにするために用意されたものです。 デシリアライズ可能なクラスの一覧をホワイトリストとして定義することで、 コードインジェクション攻撃を防ぎます。
<?php
// オブジェクトはすべて、__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]);
ICU のさらなる機能を利用するために、新しく IntlChar クラスが追加されました。このクラスには数々の static メソッドと定数が定義されており、 これらを使って Unicode の文字を操作できます。
<?php
printf('%x', IntlChar::CODEPOINT_MAX);
echo IntlChar::charName('@');
var_dump(IntlChar::ispunct('!'));
上の例の出力は以下となります。
10ffff COMMERCIAL AT bool(true)
このクラスを使うには、Intl 拡張モジュールをインストールしなければいけません。
Expectations は、かつての assert() 関数を、下位互換性を保ったまま拡張したものです。 これを用いると、コストをかけずに実運用コードの中にアサーションを組み込めます。 そして、アサーションが失敗した際に自作の例外をスローできるようになります。
これまでの API も下位互換性を保つために維持されていますが、 assert() は言語構造となりました。 最初のパラメータには、単に評価対象の文字列や bool 値を指定するだけではなく、式を渡せます。
<?php
ini_set('assert.exception', 1);
class CustomError extends AssertionError {}
assert(false, new CustomError('Some error message'));
?>
上の例の出力は以下となります。
Fatal error: Uncaught CustomError: Some error message
開発環境および運用環境での設定方法などの詳細については、 assert() のマニュアルの expectation の節を参照ください。
use
宣言のグループ化
複数のクラスや関数そして定数を同じ namespace
からインポートする際に、
単一の use
文にまとめられるようになりました。
<?php
// 以前のバージョンのコード
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 以降のコード
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};
?>
PHP 5.5 で導入されたジェネレータの機能拡張です。
ジェネレータの内部で return
文が使えるようになりました。
これを使えば、ジェネレータが最終的に返す式を指定できます (参照を返すことはできません)。
この値を取得するには、新しいメソッド
Generator::getReturn()
を用います。
このメソッドを使うのは、ジェネレータが値の生成を終えた後の一度だけになるでしょう。
<?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
ジェネレータの最終値を明示的に返せる機能は、あれば便利なものです。 ジェネレータを実行したクライアント側のコードが、 ジェネレータが最後に返す値 (何らかのコルーチンの計算結果) を特別扱いできるようになるからです。 「取得した値が最後の値かどうかをまず調べて、最後であれば特別扱いする」 という処理をクライアント側で書くよりは、ずっとシンプルになります。
ジェネレータを、別のジェネレータや
Traversable オブジェクトそして配列に委譲できるようになりました。
外側のジェネレータに決まり文句を書いたりする必要はなく、単に yield from
構文を使うだけです。
<?php
function gen()
{
yield 1;
yield 2;
yield from gen2();
}
function gen2()
{
yield 3;
yield 4;
}
foreach (gen() as $val)
{
echo $val, PHP_EOL;
}
?>
上の例の出力は以下となります。
1 2 3 4
新しい intdiv() 関数は、 オペランドに対して整数の除算を行い、その結果を返します。
<?php
var_dump(intdiv(10, 3));
?>
上の例の出力は以下となります。
int(3)
session_start() にオプションの配列を渡せるようになりました。 これは、php.ini などで設定した session 設定ディレクティブ を上書きします。
新たな設定オプション
session.lazy_write
をサポートするようになりました。これはデフォルトで有効になっており、
セッションのデータが書き換えられたときにだけセッションファイルを上書きします。
また、read_and_close
も追加されました。
このオプションは session_start() だけに渡せるもので、
セッションデータを読み込んだら何も変更せずその場でクローズするよう指示します。
たとえば、
session.cache_limiter
を private
にして、読み込んだセッションをすぐにクローズさせるには次のようにします。
<?php
session_start([
'cache_limiter' => 'private',
'read_and_close' => true,
]);
?>
新しい preg_replace_callback_array() 関数は、 preg_replace_callback() 関数を使ったコードをよりすっきりと書けるようにするものです。 これまでのバージョンの PHP では、正規表現ごとにコールバックを実行したければ、 コールバック関数が分岐だらけになってしまっていました。
PHP 7 以降では、個々の正規表現に対するコールバックを連想配列で登録できるようになりました。 連想配列のキーが正規表現で、その値がコールバックとなります。
暗号論的に安全な整数値および文字列を生成する、 プラットフォームに依存しない二つの新しい関数が追加されました。 random_bytes() と random_int() です。
これまでのバージョンでは、ArrayAccess を実装したオブジェクトに対して list() が正常に機能しないことがありました。 PHP 7 ではこの問題が修正されました。
(clone $foo)->bar()
のようにできるということです。