リリースノート
2016年4月1日に,PHP6.0がリリースされました.
PHP 6 Changelog
新機能
PHP5.6からPHP7.0への大規模なアップデートが話題になりましたが,更にPHP7.0からPHP6.0に向けて後方互換性に関わる数多くの変更が行われています.
内部文字コードUTF-16化
PHP6.0から,JavaやC#のように,処理系内部において文字列が全て文字コードUTF-16で保持されるようになります.これにより,そのままでは挙動に変化はありませんが,declare
宣言にてencoding
を明示したときに違いが表れます.
<?php
$str = '本当だよ';
echo substr($str, 0, 6); // 本当
echo mb_substr($str, 0, 2); // 本当
<?php
declare(encoding='UTF-8');
$str = '嘘じゃないよ';
echo substr($str, 0, 1); // 嘘
echo $str[0]; // 嘘
このように,従来はmbstring拡張の関数を利用して書いていたところが,通常の関数を用いて処理できるようになります.それに伴い,mbstring拡張がPHP6.0からはDeprecatedになることも決定されました.
上記の例ではUTF-8を用いましたが,今後はShift_JISで使われることが増えていくと予想されます.実際この変更が導入された背景にはBash on Windowsの発表があり,**「文字コードShift_JISで出来るだけ快適にPHPコードを書きたい」**という声も既に上がっています.
演算子の挙動変更
古くからPHPは文字列連結にはドット演算子.
,オブジェクトメンバの参照にはアロー演算子->
,連想配列の定義にはダブルアロー演算子=>
を用いていましたが,ポピュラーな他の言語との互換性を考慮して,PHP6.0からは以下のように変更されます.
$s = 'a' + 'b';
echo $s; // ab
$rows = $pdo.query('SELECT * ...').fetchAll(PDO::FETCH_ASSOC);
$assoc = [
'a': 'b',
'c': 'd',
];
なお,連想配列のキーのクオーテーションは省略することが可能です.
$assoc = [
a: 'b',
c: 'd',
];
Scalar Objects
スカラー値からメソッドが生やせるようになる nikic/scalar_objects 拡張が注目を集めていましたが,PHP6.0からはこれが標準で導入されます.基本的なメソッドも定義されています.
$r = [1, 2, 3, 4].map(function ($x) { return $x + 1; })
.map(function ($x) { return $x * 2; })
.join(',');
echo $r; // 4,6,8,10
Short Closure
Scalar Objects の採用に伴い,より短いシンタックスを実現するために,クロージャの短縮記法が導入されました.役割を失った->
はこちらで活用されます.
$r = [1, 2, 3, 4].map($x -> $x + 1)
.map($x -> $x * 2)
.join(',');
echo $r; // 4,6,8,10
また**「変数をuse
でインポートするのが煩わしい」**との声に答え,クロージャを生成したスコープに存在する変数を暗黙的にインポートする記法も用意されました.こちらでは=>
を用います.
$y = 'World';
echo ($x => "$x, $y")('Hello'); // Hello, World
Implicit Variable
PHPは歴史的な理由で,Noticeを発生しながらも未定義の定数を文字列として扱っていましたが,PHP6.0からは以下のように挙動が変更されます.
- 文字列ではなく変数名として扱われるようになる
- Noticeが発生しなくなる
よってPHP6.0からは以下のようなコーディングスタイルが推奨されます.
r = [1, 2, 3, 4].map(x -> x + 1)
.map(x -> x * 2)
.join(',');
echo r; // 4,6,8,10
Named Closure
以前のPHPでも,mpyw/phpext-calleeのようなエクステンションを作れば,クロージャを無名再帰させることが可能でした.
<?php
var_dump((function ($n) {
return $n < 2 ? 1 : $n * callee()($n - 1);
})(5));
// 5! = 5 * 4 * 3 * 2 * 1 = int(120)
PHP6.0からはJavaScriptのように,クロージャに再帰用の名前が付けられるようになります.
<?php
var_dump((function self($n) {
return $n < 2 ? 1 : $n * self($n - 1);
})(5));
// 5! = 5 * 4 * 3 * 2 * 1 = int(120)