RubyとPHP(仮) 基本的な違い(6)
2008年10月16日(木)10:13|天方
PHP5.3のSPLの新機能を試してみる
以前に、「RubyとPHP(仮) 基本的な違い(5)」で、SPLには、スタックやキュー、ヒープがあると説明しておりましたが、実際にはPHP5.3からの機能になります。現時点ではPHP5.3は開発中ですので、まだ現場では使えないかもしれませんが、先取りして、SPLの機能を触ってみたいと思います。
PHP5.3を試しに入れてみる
まず、PHP5.3をインストールすなければ何も始まりませんので、自分の環境でPHPをコンパイルしてみました。 すでに、PHP5.2が動いている環境で、そちらには影響がないように、ローカルに導入してみました。 以下に簡単な手順をまとめます。
$ cd ~/
ホームへ移動
$ wget http://snaps.php.net/php5.3-200809260430.tar.gz
php5.3のスナップショットを取得
$ tar zxvf php5.3-200809260430.tar.gz
tar.gzを展開
$ cd php5.3-200809260430
展開したディレクトリへ移動
$ mkdir /usr/local/dev
phpの配置先のフォルダを準備する
$ ./configure --prefix=/usr/local/dev --enable-calendar --enable-mbstring --with-pear
とりあえず、ちょっとほしいと思ったパラメータのみ設定
$ make
$ make test
$ make install
ビルドしてインストール
最後までエラーなどが出なければインストール完了です。私の場合はtestでいくつか警告等がでましたがphpコマンドは利用できていました。ためしにPHPを入れるだけなら簡単です。(ちなみに、こちらの環境ではコマンドラインでのみ利用することを前提としています。)
PHP5.3にどんなSPLのクラスが含まれているか確認する
まず、以下のようなphpファイルを作成します。
$ cat spl.php
<?php
print_r(spl_classes());
?>
そして、実行して、SPLのクラス一覧を出力して、ちゃんと使いたいクラスがあるかみてみます。
$ /usr/local/dev/bin/php spl.php
Array
(
[AppendIterator] => AppendIterator
[ArrayIterator] => ArrayIterator
[ArrayObject] => ArrayObject
[BadFunctionCallException] => BadFunctionCallException
[BadMethodCallException] => BadMethodCallException
[CachingIterator] => CachingIterator
[Countable] => Countable
[DirectoryIterator] => DirectoryIterator
[DomainException] => DomainException
[EmptyIterator] => EmptyIterator
[FilesystemIterator] => FilesystemIterator
[FilterIterator] => FilterIterator
[GlobIterator] => GlobIterator
[InfiniteIterator] => InfiniteIterator
[InvalidArgumentException] => InvalidArgumentException
[IteratorIterator] => IteratorIterator
[LengthException] => LengthException
[LimitIterator] => LimitIterator
[LogicException] => LogicException
[MultipleIterator] => MultipleIterator
[NoRewindIterator] => NoRewindIterator
[OuterIterator] => OuterIterator
[OutOfBoundsException] => OutOfBoundsException
[OutOfRangeException] => OutOfRangeException
[OverflowException] => OverflowException
[ParentIterator] => ParentIterator
[RangeException] => RangeException
[RecursiveArrayIterator] => RecursiveArrayIterator
[RecursiveCachingIterator] => RecursiveCachingIterator
[RecursiveDirectoryIterator] => RecursiveDirectoryIterator
[RecursiveFilterIterator] => RecursiveFilterIterator
[RecursiveIterator] => RecursiveIterator
[RecursiveIteratorIterator] => RecursiveIteratorIterator
[RecursiveRegexIterator] => RecursiveRegexIterator
[RecursiveTreeIterator] => RecursiveTreeIterator
[RegexIterator] => RegexIterator
[RuntimeException] => RuntimeException
[SeekableIterator] => SeekableIterator
[SimpleXMLIterator] => SimpleXMLIterator
[SplDoublyLinkedList] => SplDoublyLinkedList
[SplFileInfo] => SplFileInfo
[SplFileObject] => SplFileObject
[SplFixedArray] => SplFixedArray
[SplHeap] => SplHeap
[SplMinHeap] => SplMinHeap
[SplMaxHeap] => SplMaxHeap
[SplObjectStorage] => SplObjectStorage
[SplObserver] => SplObserver
[SplPriorityQueue] => SplPriorityQueue
[SplQueue] => SplQueue
[SplStack] => SplStack
[SplSubject] => SplSubject
[SplTempFileObject] => SplTempFileObject
[UnderflowException] => UnderflowException
[UnexpectedValueException] => UnexpectedValueException
)
SplDoublyLinkedList、SplHeap、SplMinHeap、SplMaxHeap、SplPriorityQueue、SplQueue、SplStackなどが使えることがわかります。
ためしにSplStackとSplQueue使ってみる
ためしにSqlStackとSplQueueを使ってみましょう。 arrayで同じことができるのですが、ここでうれしいのは、 このデータはStackとして使う、Queueとして使うということを明示的にソースで示せるということです。 これはちょっと幸せです。 (いままではそれをするには自分でクラスを作る必要がありました!)
$ cat stack.php
$stack = new SplStack();
$stack->push(1);
$stack->push(2);
$stack->push(3);
echo $stack->pop() . "\n";
echo $stack->pop() . "\n";
echo $stack->pop() . "\n";
// echo $stack->pop(); // こいつはexceptionを吐きます
$ /usr/local/dev/bin/php stack.php
3
2
1
ちゃんとスタックしてくれてます。
$ cat queue.php
$queue = new SplQueue();
$queue->enqueue(1);
$queue->enqueue(2);
$queue->enqueue(3);
echo $queue->dequeue() . "\n";
echo $queue->dequeue() . "\n";
echo $queue->dequeue() . "\n";
$ /usr/local/dev/bin/php queue.php
1
2
3
キューもしかり。
おまけ
$ cat maxheap.php
$maxHeap = new SplMaxHeap();
$maxHeap->insert(1);
$maxHeap->insert(10);
$maxHeap->insert(2);
$maxHeap->insert(5);
echo $maxHeap->extract() . "\n";
echo $maxHeap->extract() . "\n";
echo $maxHeap->extract() . "\n";
echo $maxHeap->extract();
$ /usr/local/dev/bin/php maxheap.php
10
5
2
1
おまけでSplMaxHeapのサンプルコードも示します。 insertした数字を、大きい順に取り出すことができます。 SplPriorityQueueも実装にはこのSplMaxHeapを使っているようです。
また、今回は、数値だけを格納していましたが、オブジェクトも扱うことができます。 SplMaxHeapなどの要素の比較が必要なデータ構造の場合は、そのクラスの比較メソッドをオーバーライドした派生クラスを作る必要があります。
PHP5.3はやくでないかな・・・。 今日はこの辺で。