PHP7.1.0α1 / PHP7.1の新機能 / PHP7.0.0α1 / PHP5.6
2016/06/09にPHP7.1.0のα版がリリースされていたので試してみます。
インストール
WindowsでXAMPPなのでwindows.php.netからVC14 x86 Thread Safeをダウンロード。
既にPHP7が入っているのでphpディレクトリを上書きするだけで大丈夫だろう。
プロシージャエントリポイントlibssh2_scp_recv2がダイナミックリンクライブラリlibssh2.dllから見つかりませんでした
?
解凍したPHPディレクトリに入っているlibssh2.dllをapache/bin/libssh2.dllに上書き。
これで動作する。
紹介した新機能
// 数値演算
$x = 1 + 'a'; // Warning: A non-numeric value encountered
$y = 1 + '1a'; // Notice: A non well formed numeric value encountered
$z = 1 + '1'; // 何も出ない
// list
$arr = ['hoge', 'fuga', 'piyo'];
list(2=>$foo, 1=>$bar, 0=>$baz) = $arr;
// $foo='piyo'、$bar='fuga'、$baz='hoge'になっていた
// マイナスの引数
$s = 'abcdefg'[-2]; // 'f'になる
$s = strpos('abcdefg', 'e', -2); // false 開始位置がfになる
// void
function hoge():void{
return null; // Fatal error: A void function must not return a value
}
// constのアクセス修飾子
class dummy{
const CONST1 = 1; // public
private const CONST2 = 2;
protected const CONST3 = 3;
public const CONST4 = 4;
}
var_dump(dummy::CONST1); // 1
var_dump(dummy::CONST2); // Fatal error: Uncaught Error: Cannot access private const dummy::CONST2
var_dump(dummy::CONST3); // Fatal error: Uncaught Error: Cannot access protected const dummy::CONST3
var_dump(dummy::CONST4); // 4
// 例外
try{
throw new TypeError();
}catch(ParseError | TypeError | AssertionError $e){
var_dump($e); // object(TypeError)
}
新機能で紹介した機能がたしかに使えてます。
新機能の追加
前回調査時点では実装されてなかった機能もいくつか追加されていました。
Square bracket syntax for array destructuring assignment
$a = 1;$b = 2;
[$a, $b] = [$b, $a];
var_dump($a, $b); // 2, 1
右辺の[]はarrayの短縮形ですが、左辺の[]はlistの短縮形になります。
ただしarrayと違って、listと[]を組み合わせてネストはできません。
[[$c, $d], [$e, $f]] = [[1,2],[3,4]]; // OK
list(list($c, $d), list($e, $f)) = array(array(1,2),array(3,4)); // OK
[list($c, $d), list($e, $f)] = [array(1,2),array(3,4)]; // Fatal error: Cannot mix [] and list()
最後の書き方は、右辺はOKなのに左辺がNGとなります。
なぜだろう。
[array($c,$d)] = [[1,2]]; // OK
おそらくarrayと区別が付かなくなるから。
Nullable Types
function hoge(int $i):int{
return 1;
}
function fuga(?int $i):?int{
return null; // 返り値null
}
hoge(1); // OK
hoge(null); // Fatal error: Uncaught TypeError: Argument 1 must be of the type integer, null given
fuga(1); // OK
fuga(null); // OK
fuga(); // Fatal error: Uncaught TypeError: Argument 1 must be of the type integer, none given
引数および返り値の型に?を付けると、その値はnullを許容します。
ここは珍しくPHPがJavaより厳格なところで、JavaはObject型引数にnull渡すことができますが、PHPではできません。
?を付けることでnullを許容するようになります。
ただし未指定は不可。
Forbid dynamic calls to scope introspection functions
https://wiki.php.net/rfc/forbid_dynamic_scope_introspection
extract()やfunc_get_args()みたいな一部特殊な関数を動的呼び出しできないようになった。
と書いてあるのですが、いまいちよくわかりません。
いや、確かに動きは違うんだけど、発動条件がよくわからないのと、そもそも誰がこんな書き方するんだっていう。
現在のスコープによる?
その他
UPGRADINGに細々とした変更が記載されています。
The ASCII 0x7F Delete control character is no longer permitted in unquoted identifiers in source code.
0x7Fがソース中に書けなくなりました。
とあるのですが、試してみたところでは、5.4.16ではParse errorになるのに
7.1.0αではWarning: Unexpected character in input: ' ' (ASCII=127) state=0
というE_WARNINGが出るけど動作はしました。
よくわからん。
If the error_log is set to syslog, the PHP error levels are mapped to the syslog error levels.
error_logの出力先がsyslogの場合、PHPのエラーレベルがsyslogのエラーレベルにマッピングされるようになったみたい。
でもLOG_DEBUGに対応するE_ってなんだ。
When calling json_encode with JSON_UNESCAPED_UNICODE option, U+2028 and U+2029 are escaped.
U+2028とU+2029はJSON_UNESCAPED_UNICODE付きでjson_encodeしてもエスケープされるよ。
json_encode() accepts new option JSON_UNESCAPED_LINE_TERMINATORS
JSON_UNESCAPED_LINE_TERMINATORS付きでjson_encodeするとU+2028とU+2029はエスケープされないよ。
もっとも、これらをエスケープしない理由はほぼ無いので、付ける必要はないと思います。
The first $varname argument for getenv() is no longer mandatory
getenv()の第一引数を省略した場合は全値が配列で返ってくる。
おまけその1
3v4lが既に7.1.0α1対応してた。はえーよ。
おまけその2
プロパティの型指定がついにRFC通りそうだ。
https://wiki.php.net/rfc/typed-properties
class Foo {
public int $int = 1;
public float $flt = 2.2;
public array $arr = [];
public bool $bool = false;
public string $string;
public callable $callable;
public stdClass $std;
public OtherThing $other;
public $mixed;
}