PHP7.1α1の新機能

[PHP7.1.0の新機能](http://qiita.com/rana_kualu/items/f8baf30752928346bef8) / [PHP7.1β1の新機能](http://qiita.com/rana_kualu/items/572494021917fbb93c95) / [PHP7.1α1の新機能](http://qiita.com/rana_kualu/items/476385b674d27339f911) / [PHP7.1.0α1インストール](http://qiita.com/rana_kualu/items/3540a960ab442e57d48e) / [PHP7.0.0α1](http://qiita.com/rana_kualu/items/447995347acb2f8997a3) / [PHP5.6](http://qiita.com/rana_kualu/items/206d786a2be7942c6dc3)

PHP7.1に導入決定・実装完了した[RFC](https://wiki.php.net/rfc#Implemented)を見てみます。

## [Warn about invalid strings in arithmetic](https://wiki.php.net/rfc/invalid_strings_in_arithmetic)
非数値文字列の数値演算でエラーが発生する。

```php
	$x = 1 + 'a';  // Warning: A non-numeric string encountered
	$y = 1 + '1a'; // Notice: A non well formed numeric string encountered
	$z = 1 + '1';  // 大丈夫っぽい
	
	$x = (1 + (int)'a'); // 回避手段1
	$x = @(1 + 'a'); // 回避手段2
```

数値として解釈可能であればE_NOTICE、完全に数値でなければE_WARNINGになるみたい。
PHP使いにとってはわりかし致命的っぽいですが、$zで問題なければまあ大丈夫でしょう。

## [Allow specifying keys in list()](https://wiki.php.net/rfc/list_keys)
list()にキーが使えるようになる。

```php
	// 配列
	$arr = ['hoge', 'fuga', 'piyo'];
	list(2=>$foo, 1=>$bar, 0=>$baz) = $arr;
	
	// 連想配列
	$arr = ['x'=>'xx', 'y'=>'yy', 'z'=>'zz'];
	list('y'=>$y, 'z'=>$z, 'x'=>$x) = $arr;
	
	// 不要な列
	$arr = ['foo', 'bar', 'baz'];
	list( 1=>$a ) = $arr;
```

`$foo='piyo'、$bar='fuga'、$baz='hoge'、$x='xx'、$y='yy'、$z='zz'、$a='bar'`になります。

```php
	// foreach
	$points = [
	    ['x' => 1, 'y' => 3],
	    ['x' => 2, 'y' => 4]
	];
	foreach ($points as list('x' => $x, 'y' => $y)) {
	    echo "x=$x, y=$y";
	}

	// 変数の入れ替え
	list('foo'=>$bar, 'bar'=>$foo) = ['foo'=>$foo, 'bar'=>$bar];
```

foreachで多重配列を展開できたり、変数の入れ替えが可能になるみたい。

## [Generalize support of negative string offsets](https://wiki.php.net/rfc/negative-string-offsets)
多くの文字列関数がマイナスの引数を受け取る。

```php
	$str = 'abcdefg';
	
	// 文字列関数
	strpos($str, 'fg', -3); // 1
	strpos($str, 'fg', strlen($str)-3); // これと同じ
	
	// 文字列添字
	$str[-2]; // f
	$str[-3] = 'h'; // $str='abcdhfg'になる
```

元々substrではマイナスの引数が使えましたが、使用可能な関数が拡大するみたいです。
変わったところではfile_get_contentsにも使えるようになるみたいですが、このオフセット機能って使ってる人いるんですかね。

ところで中に`『Recommend using '{}' vs '[]' for string offsets』`というセクションがありますが、みんなはどちら派でしょうか。
`'abcdefg'[1]` 、`'abcdefg'{1}`、現在は何れでもアクセス可能ですが、何れはどちらかに寄せた方がよいでしょう。

## [OpenSSL AEAD support](https://wiki.php.net/rfc/openssl_aead)
OpenSSLの認証付き暗号Authenticated Encrypt with Associated Dataに対応する。

といっても[AEAD](https://ja.wikipedia.org/wiki/%E8%AA%8D%E8%A8%BC%E4%BB%98%E3%81%8D%E6%9A%97%E5%8F%B7)がよくわからん。
実用的にはopenssl_encryptとopenssl_decryptに引数が追加されるだけみたい。
OpenSSL関数はopenssl_random_pseudo_bytesくらいしか使ったことない。

## [Void Return Type](https://wiki.php.net/rfc/void_return_type)
返り値の型voidが追加される。

```php
function hoge(): void {
    return null; // Fatal error: A void function must not return a value
    return; // OK。もしくはreturnを書かない。
}
```

Javaのvoidと同じ。
nullではなく、明示的に何も返さないことを表明したいときに指定する。
ただ`$hoge=hoge();`としたときに`$hoge`がどうなるのかは記載がない気がする。null？

## [Support Class Constant Visibility](https://wiki.php.net/rfc/class_const_visibility)
クラス内constのアクセス修飾子をサポート。

```php
class dummy{
	          const CONST1 = 1; // public
	private   const CONST2 = 2;
	protected const CONST3 = 3;
	public    const CONST4 = 4;
}
```

ますますdefineがいらない子に。
あと中にしれっと`const A=1,B=2;`みたいな記法が載ってて、何気にPHP5.4でも動いたんだけど、[こんな説明どこかにあったっけ？](http://php.net/manual/ja/language.constants.syntax.php)

## [ext/curl HTTP/2 Server Push Support](https://wiki.php.net/rfc/curl_http2_push)
curlがHTTP/2に対応する。

HTTP/1.1以来16年ぶりのバージョンアップである[HTTP/2](https://ja.wikipedia.org/wiki/HTTP/2)に対応。
まあPHPから呼ぶときはほとんど関係ない気はしますが。

## [IntlTimeZone::getWindowsID()](https://wiki.php.net/rfc/intl.timezone.get-windows-id)
ICUのgetWindowsIDに対応。

といってもそもそも[ICU](http://icu-project.org/apiref/icu4c/classicu_1_1TimeZone.html)って何レベルなので、これが何なのか全くわかりません。
DateTimeZoneとかのWindows版？

## [Catching Multiple Exception Types](https://wiki.php.net/rfc/multiple-catch)
複数の例外キャッチに対応。

```php
	// PHP7.1
	try{
		// なんかコード
	}catch(ParseError | TypeError $e){
		// ParseErrorまたはTypeErrorをcatch
	}catch(AssertionError $e){
		// AssertionErrorをcatch
	}
	
	// これまで
	try{
		// なんかコード
	}catch(ParseError $e){
		// ParseErrorをcatch
	}catch(TypeError $e){
		// TypeErrorをcatch
	}catch(AssertionError $e){
		// AssertionErrorをcatch
	}
```

これまでは真面目に例外処理しようとすればするほど面倒で、もういいやExceptionキャッチしとけってなりがちでしたが、その手間をだいぶ抑えることができるようになりそうです。

これと似たような話として[Union Types](https://wiki.php.net/rfc/union_types)ってRFCがあるのですが、こちらはさすがにどうだろう？

```php
	function hoge(int | string $var){
		// $varはintかstring
	}
```

## まとめ

negative string offsets、Class constant visibility modifiers 、Catching Multiple Exception Typesは間違いなく便利。
Warn about invalid strings in arithmeticは言語としては正しい方向だけどPHPとしてはどうだろう。
Allow specifying keys in list()は便利そうだけど、そもそも私はlistを全く使わないのでなんとも言えないな。

なお、PHP7.1は[2016年10月リリース予定](https://wiki.php.net/rfc/php7timeline)です。