PHP7.1.0α1をインストール

[PHP7.1.0α1](http://qiita.com/rana_kualu/items/3540a960ab442e57d48e) / [PHP7.1の新機能](http://qiita.com/rana_kualu/items/476385b674d27339f911) / [PHP7.0.0α1](http://qiita.com/rana_kualu/items/447995347acb2f8997a3) / [PHP5.6](http://qiita.com/rana_kualu/items/206d786a2be7942c6dc3)

2016/06/09に[PHP7.1.0のα版がリリースされていた](http://php.net/)ので試してみます。

## インストール

WindowsでXAMPPなので[windows.php.net](http://windows.php.net/qa/)からVC14 x86 Thread Safeをダウンロード。
既に[PHP7が入っている](http://qiita.com/rana_kualu/items/447995347acb2f8997a3)のでphpディレクトリを上書きするだけで大丈夫だろう。

> プロシージャエントリポイントlibssh2_scp_recv2がダイナミックリンクライブラリlibssh2.dllから見つかりませんでした

？
解凍したPHPディレクトリに入っているlibssh2.dllをapache/bin/libssh2.dllに上書き。
これで動作する。

## 紹介した新機能

```php
	// 数値演算
	$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

https://wiki.php.net/rfc/short_list_syntax

```php
	$a = 1;$b = 2;
	[$a, $b] = [$b, $a];
	var_dump($a, $b); // 2, 1
```

右辺の[]はarrayの短縮形ですが、左辺の[]はlistの短縮形になります。
ただしarrayと違って、listと[]を組み合わせてネストはできません。

```php
	[[$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となります。
なぜだろう。

```php
	[array($c,$d)] = [[1,2]]; // OK
```

おそらくarrayと区別が付かなくなるから。

### Nullable Types

https://wiki.php.net/rfc/nullable_types

```php
	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()みたいな一部特殊な関数を動的呼び出しできないようになった。
と書いてあるのですが、いまいちよくわかりません。
いや、[確かに動きは違う](https://3v4l.org/JT99E)んだけど、発動条件がよくわからないのと、そもそも誰がこんな書き方するんだっていう。
現在のスコープによる？

## その他

[UPGRADING](https://github.com/php/php-src/blob/php-7.1.0alpha1/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対応してた](https://3v4l.org/WgjiY)。はえーよ。

## おまけその2

プロパティの型指定がついにRFC通りそうだ。
https://wiki.php.net/rfc/typed-properties

```php
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;
}
```