

[ArrayAccess](http://php.net/manual/class.arrayaccess.php)を実装すれば、自作のクラスのインスタンスオブジェクトを配列のように利用することができそうです!

しかし、`array_map`などの配列系の標準函数には利用できませんでした。

以下のコードでは簡単のために、SPLに含まれる[ArrayIterator](http://php.net/manual/class.arrayiterator.php)を例にとります。

[code]

    <?php
    array_map('gettype', array_map('floatval', [1, 2, 3]));
    // ["double", "double", "double"]
    
    array_map('gettype', array_map('floatval', new ArrayIterator([1, 2, 3])));
    // PHP Warning:  array_map(): Argument #2 should be an array in /tmp/array_access.php on line 5
    // PHP Warning:  array_map(): Argument #2 should be an array in /tmp/array_access.php on line 5
    
[/code]

自作のオブジェクトや`ArrayIterator`などの`ArrayAccess`を実装したクラスのインスタンスを配列と区別なく利用したいのですが、何か解決策はありますか?

タイプヒントで`array`を期待する箇所で利用できると、もっと嬉しいです。


CC BY-SA 3.0
2014-12-06T19:25:00.650
408
2014-12-16T10:40:40.810
2014-12-07T06:25:17.650
728
938
question
php
array_mapにArrayAccessを実装したオブジェクトを利用する方法はありますか?


タイトルにある `array_mapにArrayAccessを実装したオブジェクトを利用する方法`  
という意味ですと、`ArrayIterator::getArrayCopy`や`iterator_to_array`を使って配列に変換すれば可能とは思いますが、

[code]

    array_map('gettype', array_map('floatval', (new ArrayIterator([1, 2, 3]))->getArrayCopy()));
    array_map('gettype', array_map('floatval', iterator_to_array(new ArrayIterator([1, 2, 3]))));
    
[/code]

`配列と区別なく利用したい`という事ですと、「`ArrayIterator`は配列で無くオブジェクトである」、「配列はオブジェクトではない」となりますのでArrayIteratorを配列そのものとして扱うのは残念ながらできないと思います。

[code]

    <?php
    
    $iterator=new ArrayIterator([1, 2, 3]);
    $array=[1,2,3];
    
    var_dump(is_array($array));
    var_dump(is_array($iterator));
    
    var_dump(is_object($array));
    var_dump(is_object($iterator));
    
[/code]

結果:

[code]

    bool(true)
    bool(false)
    bool(false)
    bool(true)
    
[/code]

英語版stackoverflowでも[同様の質問](https://stackoverflow.com/questions/8788002/arrayaccess-
and-native-php-array-functions)がありました。

phpの配列用関数をArrayAccessで使えないかという質問で、  
同様のメソッドを自分のオブジェクトに実装するしかないという回答になっています。


CC BY-SA 3.0
2014-12-07T03:26:57.130
416
2014-12-07T03:26:57.130
2017-05-23T12:38:55.250
-1
728
408
answer


まず、`array_map` を適用したくなるのは `ArrayAccess` ではなく `Traversable` じゃないでしょうか。
`ArrayAccess`
には要素を走査したり、添え字の一覧を取得するようなインターフェイスは含まれないので、そういった関数を実装すること自体難しいように思います。

`array` でも `Traversable` でも同様に扱えるライブラリを使うのはどうでしょうか。

  * <https://github.com/nikic/iter>
  * <https://github.com/yuya-takeyama/F.php>

いずれも遅延評価を用いているので、対象がメモリにおさまりきれない要素数を持っていても、適用可能です。  
(巨大なファイルの `SplFileObject` 等)


CC BY-SA 3.0
2014-12-16T10:40:40.810
1740
2014-12-16T10:40:40.810
3025
408
answer