FLATzブログ

[RubyとPHP(仮)]の記事一覧

RubyとPHP(仮) 基本的な違い(6)

2008年10月16日(木)10:13|amakata|FLATzブログ, PHP, RubyとPHP(仮), 技術情報このエントリをdel.icio.usに追加このエントリをはてなブックマークに追加

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はやくでないかな・・・。
今日はこの辺で。

続きを読む


訂正:「RubyとPHP(仮) 基本的な違い(2)」 – PHPの整数型の扱い

2008年09月25日(木)09:35|amakata|FLATzブログ, PHP, RubyとPHP(仮), 技術情報このエントリをdel.icio.usに追加このエントリをはてなブックマークに追加

以前に、RubyとPHP(仮) 基本的な違い(2)
RubyとPHPのデータ型を比較しました。


そこで


Rubyでは、Fixnumの範囲を超える値は自動的にBignumに変換されるため、プラットフォームが変わっても、パフォーマンス以外には問題がおこりません。しかし、PHPでは、環境によっては桁が足りないなどの問題が発生する可能性があります。


と説明をしましたが、これだけでは説明が足りておりませんでした。


それは、PHPでもintのサイズ範囲外になった際に、型変換が起こるというものです。
PHPでは、intのサイズを超える場合にはfloat型になります。
たとえば



<?php
$intmax = 2147483647;
$int1 = 1;
$intover = $intmax + $int1;
echo var_dump($intmax);
echo var_dump($int1);
echo var_dump($intover);
?>


のようなコードを実行するとします。


すると、int型とint型を足しても、範囲外の場合にはfloat型になります。



amakata@flatz $ php int.php
int(2147483647)
int(1)
float(2147483648)


したがって、floatの精度までは利用できることになります。
ただ、float型では、有効数字に制約があるのでRubyのように精度が保証されるとは限らないことを注意しておいたほうがよいでしょう。

続きを読む


Page 1 of 41234»

このページの先頭へ