PHPの配列は手続き的なのか
前回のRubyとPHP(仮) 基本的な違い(4)ではRubyとPHPの配列の違いについて比べてみました。
その際、Rubyにはオブジェクト指向的なインタフェースがあって、PHPには手続き的なインタフェースがあるという説明をしました。実はPHPにも配列をオブジェクト指向的なインタフェースで操作する方法が用意されているのです。あまりなじみがないかもしれませんが、この機能はPHP5で標準で組み込まれたSPL(Standard PHP Library)で提供されています。SPLはおそらくC++のSTL(Standard Template Library)の影響を強くうけてつくられたライブラリだと思うのですが、PHPではSPLを使って配列を操作している場所をみたことがないです (- – ;
ではどんな風に操作するのか説明してみたいと思います。
はじめてのSPL(ArrayObject)
SPLで配列を使うにはSPLのArrayObjectクラスを利用します。
例えば、以下のようにすることで配列をArrayObjectとして扱うことができるようになります。
<?php
$array = array(1, 2, 3, 4);
// ArrayObjectを作成
$arrayObj = new ArrayObject($array);
// $arrayObjを配列のように利用可能>
foreach ($arrayObj as $element) {
echo $element;
}
echo $arrayObj[0];
echo $arrayObj[1];
echo $arrayObj[2];
echo $arrayObj[3];
?>
ArrayObjectを使うとなにがいいかというと配列の操作にメソッドを使える点です。
例えば、
$arrayObject->append(5);
のようにして、末尾に要素を追加したり、
$arrayObject->count()
で要素数を取得したりできます。
ただ、ArrayObjectには制限もあります。
それは配列の先頭や途中に要素を追加することができない点などです。
どういったことができるかどうかは、SPLのマニュアルを参照してください。
ArrayObjectを利用した場合の良さは、イテレータで繰り返しを汎用的に記述できる点でしょう。
$itr = $arrayObj->getIterator();
while ($itr->valid()) {
echo "key: " . $itr->key() . " current: " . $itr->current() . "\n";
$itr->next();
}
のように記述することで、$arrayObjの配列の添え字(key)と要素(current)を順番に取り出すことが可能です。
自分でカスタムのIteratorを定義することも可能です
// 通常のArrayIteratorはリピートしてしまうのでカスタム化
class CustomArrayIterator extends ArrayIterator{
public function next(){
if( parent::valid() ){
return parent::next();
}
return;
}
}
// Iteratorを指定してArrayObjectを利用
$arrayObj = new ArrayObject($array, 0, "$arrayObj = new ArrayObject($array);");
$itr = $arrayObj->getIterator();
while ($itr->valid()) {
echo "key: " . $itr->key() . " current: " . $itr->current() . "\n";
$itr->next();
}
このように繰り返しの動作をデータ構造とは別に定義しておくことが可能です。
ArrayObject以外のSPL
SPLではArrayObject以外にSplDoublyLinkedList、SplStack、SplQueue、SplHeap、SplPriorityQueueなどのデータ構造もIteratorを使ってアクセスすることができます。
次回はそれらのアクセスについても簡単に紹介したいと思います。