PHP の strval が使いづらい。
PHP の strval 関数のマニュアルPHP: strval - Manualに
strval() は配列に対して使うことはできず、 __toString メソッドを実装していないオブジェクトに対しても使うことはできません。
という記述があるけれども、これはドキュメントとしておかしいと思う。
『使うことはできません』とかいったところで実際渡せてしまうのだから、書くべきなのは、どうなってしまうのか、あるいはその関数の実装側としてクライアントにどうしてほしいのかだと思う。
『配列、もしくは__toString メソッドを実装していないオブジェクトを strval に渡した結果は未定義とします。』
とか、
『strval はスカラー値を文字列化することを想定しているため、配列、もしくは__toString メソッドを実装していないオブジェクトを渡さないでください。』
とか、そういうふうに書かないとドキュメントとして体をなしてない。
で、
実際のところ渡すとどうなるかというと、配列を渡すと "Array" という文字列になり、__toString のないオブジェクトを渡すと実行時エラーが上がりつつ空文字列がかえってくる。
さらに TRUE を渡すと "1" が返ってきて、 FALSE を渡すと空文字列が返って来たりする・・・
・・・誰が得するんだこの仕様。
エラーが上がってくる可能性があるということは、この関数は実際のオブジェクトの型がわからない場合には使ってはいけないということになる。つまりこの関数のクライアントは渡した型を把握してなきゃいけない。で、渡した型が型がわかってるんだったら、配列が "Array" になっても何も嬉しくない。
配列が "Array" になるのであれば、文字列化できないオブジェクトは "Object" とでも返ってくればよかった、そうすれば少なくともエラーになることはないんだからテキトーに渡せる。
というか、私がほしい物作った。
自然に文字列にできるときは文字列にし、できないときは概略情報を文字列化する。
Class Text{
public static function ToString( $o ){
// NULL は空文字列、文字列はそのまま、数値っぽかったら strval
// NULL は 'null' という文字列と悩んだが、空文字列が一番使い勝手が良いっぽい。
if( is_null($o)) return '';
if( is_string($o)) return $o;
if( is_numeric($o)) return strval($o);
// bool は true/false に
if( is_bool($o)){
if( $o === TRUE ) return 'true';
if( $o === FALSE ) return 'false';
}
// object は __toString の有無によって挙動を変える、
if (is_object($o)){
if( in_array( "__toString", get_class_methods($o))){
return strval($o->__toString());
}else{
return get_class($o) . ":" . spl_object_hash($o);
}
}
// 配列は内容をトップレベルのみ表示
if( is_array( $o ) ){
// Text::ArrayToString は、再帰しない、改行しない print_r みたいな関数。(別に作った)
return self::ArrayToString($o);
}
// リソースがここまで来るが、リソース ID が表示されるstrvalの挙動で良いので、
return strval($o);
}
}