却下されたPHP RFCを見てみる その3

[その1](http://qiita.com/rana_kualu/items/644def9847b116c8f108) / [その2](http://qiita.com/rana_kualu/items/180990033bd9b1b2c316) / [その3](http://qiita.com/rana_kualu/items/09e85bf84175a9b82e11)

## Declined RFC

PHP7で却下されたRFC特集、今回で最後です。
これより前のRFCはPHP5だから、遡ってもあまり意味がないしね。
また却下が増えたら続きやるかも。

### [User defined session serializer](https://wiki.php.net/rfc/user_defined_session_serializer)

賛成9/反対10で却下。

セッションデータのシリアライズは[session_encode](http://php.net/manual/ja/function.session-encode.php)という関数で行われています。
この挙動は[session.serialize_handler](http://php.net/manual/ja/session.configuration.php#ini.session.serialize-handler)で変更することが可能ですが、何故かphp_serialize|php_binary|wddxしか対応していません。
そこで任意のシリアライズ方法を実装できる関数session_set_serializer()を実装しようという提案。

```php
	// 第一引数はエンコード、第二引数がデコード
	session_set_serializer(function($data){
		return json_encode($data);
	},functiion($string){
		return json_decode($string, true);
	});
	
	session_start();
```

なぜ却下されたかはよくわかりませんが、[PHPのえらい人](http://withgod.hatenablog.com/entry/2014/07/12/210316)から[ログがうぜー](https://github.com/php/php-src/pull/2205#issuecomment-261192410)とか言われてたのでその可能性。


### [Add PHP Engine Identifier Constant](https://wiki.php.net/rfc/php_engine_constant)

賛成8/反対9で却下。

普通のPHPとHHVMの区別は定数HHVM_VERSIONでできるけど、これはHippyVMとかが対応してない。
PHP_VERSIONでは'7.0.99-hhvm'みたいな文字列になってるから識別が面倒。
なので`PHP_ENGINE = 'php'、'hhvm'`みたいな単純な識別用定数を作ろうぜ、という提案。
あとついでにPHP_ENGINE_VERSIONとかPHP_ENGINE_VERSION_IDとかPHP_ENGINE_RELEASE_VERSIONとかPHP_ENGINE_EXTRA_VERSIONとかも作ろうぜ。

これは過半数で通過するというルールだったのですが、わずかに届かず敗退。
たぶんPHP_ENGINEだけだったら通ったんじゃないかなあと思うのですが、余計な提案がくっついてきてたので面倒になった印象。


### [Add validation functions to filter module](https://wiki.php.net/rfc/add_validate_functions_to_filter)

賛成1/反対14で却下。

バリデーション関数を増やそうという提案。

```php
	mixed filter_require_var ( mixed $variable , int $filter [, mixed $options ] )
	array filter_require_var_array ( array $data , mixed $definition [, int $function_options ] )
	mixed filter_require_input ( int $type , string $variable_name , int $filter [, mixed $options ] )
	array filter_require_input_array ( int $type , mixed $definition [, int $function_options ] )
	bool filter_check_definition (array $definition_of_array_value_filter_and_validation)
```

似たような関数増えすぎでわけがわからないよ。
ここまで来たらもう、関数じゃなくてFilterクラスとか作ってそっちでやってくれって感じですね。


### [Using objects as keys](https://wiki.php.net/rfc/objkey)

賛成6/反対24で却下。

配列のキーにオブジェクトを入れられるようにしようという提案。

```php
	class HOGE{
		public function __hash(){ return 'fuga'; }
	}
	
	$array = [ ( new HOGE() ) => true];
	var_dump($array); // array(1){ ["fuga"]=>bool(true) }
```

実際にキーがオブジェクトになるわけではなく、単にマジックメソッド__hash()の返り値に置き換えられるだけみたい。
意味あるのかこれ？
どうせやるんだったらオブジェクト自体をキーにできるくらいのことはしてもらわないと。


### [Abstract final classes / Static classes](https://wiki.php.net/rfc/abstract_final_class)

賛成5/反対12で却下。
とりあえずシンタックスハイライトがきちんとできてない時点で駄目そう感溢れる。

`static class`もしくは`abstract final class`を導入してくれという提案。
要するにインスタンス化できないクラスがほしいということみたいだけど、どうあがいても定数クラスになる未来しか見えない。


### [Access to aliases definition by reflection](https://wiki.php.net/rfc/aliases_by_reflection)

賛成1/反対10で却下。

```php
use Library\Http;
class Factory{
	/** @return Http\Client */
	public function createClient(){
		return new Http\Client;
	}
}
```

この`Http\Client`が`\Http\Client`なのか`\Library\Http\Client`なのかわからない、だからReflectionClassとReflectionFunctionにgetDefinedAliases()メソッドを増やそうぜ、と書いてあるみたいなんだけど、`get_class($factory->createClient())`でふつーに`Library\Http\Client`って取れるんだよね。
なので既に何の主張なのかわからなくなってる感。

getDefinedAliases()では[インポート・エイリアス定義](http://php.net/manual/ja/language.namespaces.importing.php)している名前空間やクラスなどの一覧を取得する、要するにuse行の一覧を取得できる予定でした。


### [Safe Casting Functions](https://wiki.php.net/rfc/safe_cast)

賛成5/反対16で却下。

intval()はどんな値に対しても動作する。
"123abc"はまだしも、リソースやオブジェクト、あまつさえnullにすら平然と対応して0とか1になってしまう。
こいつは柔らかすぎて逆に困るので、きちんと数値型文字列にしか反応しない関数try_int()/to_int()を作ろう、という提案。
to_int()は失敗するとCastExceptionを発生し、try_int()はnullを返します。
要するに[Integer.parseInt()](https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Integer.html#parseInt-java.lang.String-int-)がほしいといったところでしょうか。


### [Loop + or control structure](https://wiki.php.net/rfc/loop_or)

賛成4/反対11で却下。

foreachelseがほしい。

```php
	while($cond){
		// なんかループ
	}or{
		// 一度もループしなかったとき
	}
	
	foreach($loop as $k=>$v){
		// なんかループ
	}or{
		// 一度もループしなかったとき
	}
	
	for($i=0; $i<$max; $i++){
		// なんかループ
	}or{
		// 一度もループしなかったとき
	}
```

そのくらい普通に書けばええやん。


## まとめ

まあなんというか、却下されても仕方ないRFCも多いんじゃないかなあと。

[Loop+Else control structure](https://wiki.php.net/rfc/loop_else)というRFCがDraftなのですが、これ上で却下されたLoop+or control structureじゃないか。
と思ったらLoop+Elseのほうが提出が先で、でも話が進んでないうちにloop+orが颯爽と飛び出していって頓死したみたい。
なんかDraftやUnder Discussion状態でも生きてるのか死んでるのか判らないRFCも多いので、いったん整理したほうがいい気がしないでもない。