181
176

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PHPAdvent Calendar 2014

Day 19

PHPのイカれたメンバーを紹介するぜ!

Last updated at Posted at 2014-12-19

公式リファレンス、読んでる?

「関数についてちょっと分からなくなってGoogle先生経由で来るところ」では勿体ない。
暇な時間に適当にリンクを踏んでいると面白いものを見つけることが出来ます。
in_arrayの第三引数であったり、strtrに渡せる配列であったり、__その他の基本モジュール__であったり・・・

「その他の基本モジュール」とは

PHP公式リファレンスの果てに広がる闇である。
本日はその一部についてご紹介したいと思います。
各タイトルに公式リファレンスへのリンクを用意しておいたので、気になったものはそちらで詳細を確認して下さい。

1. SPL (Standard PHP Library)

http://php.net/manual/ja/book.spl.php

みんな大好きSPL。
DirectoryIteratorとかすごく便利。
ディレクトリパスをコンストラクタに渡すと、ディレクトリ内部のファイルを舐めるイテレータになります。

DirectoryIterator
$dir = new DirectoryIterator('/directory/path');
foreach ($dir as $file)
{
  echo $file->getFileName();
}
結果
aaa.txt
bbb.txt ...

他にもファイルそのものをオブジェクトとして扱うSplFileObject (CSVを扱うときに便利)、
foreachで回せるものなら何でもイテレータに変えてしまうIteratorIteratorなど、
便利なオブジェクトが標準で幾つも用意されています。
ドキュメントも充実しているので、気になるものを見つけたら明日から早速活用してみてください。

2. SPL Types (厳格な型定義)

http://php.net/manual/ja/book.spl-types.php

こちらはSPL(Standard PHP Library)を名乗っている癖に、PECL拡張なのでインストールが必要です。
以下のコマンドを打った後に出力されるExtensionパスをphp.iniに追記してWebサーバを再起動してください。

インストール方法
# PECL install SPL_Types

警告

この拡張モジュールは、実験的 なものです。この拡張モジュールの動作・ 関数名・その他ドキュメントに書かれている事項は、予告なく、将来的な PHP のリリースにおいて変更される可能性があります。 このモジュールは__自己責任__で使用してください。

http://php.net/manual/ja/intro.spl-types.php

リファレンスの警告文から早くもヤバい空気を感じる。
ここが「その他の基本モジュール」の闇の入り口だ。

さてこのSPL Types、何が出来るのかというと、例を示したほうが早いと思います。
公式リファレンスから一部を改変して引用します。

Example
$integer = new SplInt;

try {
    $integer = '文字列を代入';
} catch (UnexpectedValueException $e) {
    echo $e->getMessage();
}
結果
Value not an integer

SplIntはSplTypeを継承したクラスなのですが、なんと__別の型の値を代入__するだけで__例外が発生__します。
それにより、__変数に格納可能な型を厳格に定義__することがこのクラスの目的です。

SplTypeを継承したクラスはSplInt, SplFloat, SplString, SplBoolの4型と、Listを厳格に定義するSplEnumがあります。
他にも色々と試してみましょう。

Example2
// Float型を入力
$integer = new SplInt(1);
$integer = 1.5;  // Exception

// SplIntを代入
$integer2 = new SplInt(2);
$integer = $integer2; // OK!

// SplFloat, SplStringを代入
$float = new SplFloat(1.2);
$text  = new SplString('text');
$integer = $float; // Exception
$integer = $text;  // Exception

// SplInt同士で乗算してstringを代入
$new_integer = $integer * $integer;
$new_integer = 'text'; // Exception

// 乗算結果を出力
$integer = new SplInt(5);
echo $integer;
echo $integer * $integer;
結果
5
25

普通に代入や計算を行っても内部の値が出力されるし、
演算後もSplTypeオブジェクトを保っていることが確認できました。

Example3
$integer  = new SplInt(3);
$integer2 = new SplInt(3);

if ($integer === $integer2) {
  echo 'OK';
}
else {
  echo 'NG';
}
結果
NG

!?
どうしてこうなった。

Example4
$integer  = new SplInt(3);
$integer2 = new SplInt(3);

if ($integer == $integer2) {
  echo 'OK';
}
else {
  echo 'NG';
}
結果
OK

なぜかこれなら通る。
よく見たらこれも公式リファレンスに記述がありました。

一致演算子(===)を使用する場合、オブジェクト変数は、
同じクラスの同じインスタンスを参照する場合のみ、 等しいとされます。
http://php.net/manual/ja/language.oop5.object-comparison.php

数値のように見えても$integerと$integer2は別々のインスタンスなので、一致演算子では別物と認識されるわけです。
なるほど、SplType関連オブジェクトを利用する場合は「==」を使いましょう。
あとis_intやis_stringは利きません。オブジェクトだもんね。

こちらのクラス、とても面白い挙動をするのですが自分には有効活用法がイマイチ見出せません。
良い使い方を知っているよという方はコメントで教えていただけると嬉しいです。

3. Taint (汚染検出)

http://php.net/manual/ja/book.taint.php

「汚染」の名を持つ拡張モジュールです。名前からして闇な感じがする。
ONにすると、HTTPリクエストで受け取った全ての値($_REQUEST, $_GET, $_POST ...)について、
特定の関数でエスケープを行うまで、その値が「汚染されている」という警告を出し続けます。
要するに、__SQLインジェクションやXSSの可能性のある値を自動的に検出__することが出来るようになるわけです。
WAFに導入しても意味が無い気がしますが、オレオレフレームワークを作っている方にはオススメかもしれません。

こちらもPECLからインストールする必要があります。
が、なんとこちらのモジュール、PHP5.2から5.4という限られた範囲でしかインストール出来ない模様
自分が常用している環境はPHP5.5.20なので導入不可能! ふざけんな!
これだけのために新しい環境を立ち上げるのもちょっと大げさなので今回は紹介だけに留めておきます。

興味のある方はウェブサーバのルートディレクトリ以下で以下のコマンドを実行してください。
インストール完了後に表示されるExtensionパスをphp.iniに書き込んでWebサーバを再起動です。

install
# PECL install Taint

4. V8js (V8 Javascript Engine 統合)

http://php.net/manual/ja/book.v8js.php

こちらはGoogleの開発しているjavascriptエンジン、「V8」をPHPで扱えるようにするためのモジュールです。
導入するとPHP上でjavascriptのコードを動かせるようになります。
最後に定義した変数が戻り値となってPHPの世界に戻ってくるようです。

例によってPECLでインストールをキメます。
普通にv8jsと打つと「今んとこβ版しかねーからバージョン指定しろよ」と怒られるので注意しましょう。

install
# PECL install v8js-0.1.5

またこちらのモジュールはV8 Engineを利用するので、そちらをビルドしてパスを通しておく必要があります。
色々な参考文献を漁ったところ、googleのSVNから落としてきてsconsするだけでビルドできるよ、とか書いてあるのですが、こんな警告が出て怒られます。

install
scons: *** No SConstruct file found.
File "/usr/lib/scons/SCons/Script/Main.py", line 834, in _main

こちらの問題はまだ解決出来ていないので、詳細わかり次第記事にしたいと思います。

公式リファレンスを読むと分かるのですが、こちらのモジュールには「V8Js::registerExtension」という、
Javascript拡張を登録する関数が用意されています。
要するにプラグイン置き場ですね。

こちらを利用することで、__PHP上でjQueryを利用したスクレイピングが行える__であろうとの目算を立てています。
実現したらテストコードと記事を公開したいと思います。
Goutteでやれとか言わないの。

underscore.jsとか入れたら強力な関数型プログラミングもできますね。
underscore.phpでやれとか言わないの。

5. Parsekit

http://php.net/manual/ja/book.parsekit.php

PHP スクリプトをコンパイルした opcode を実行時に解析することができます。

お前は何を言っているんだ?
今回紹介するモジュールの中では最も闇感つよい。

PHPはまず中間コードであるオペコードに変換され、それをZend VMが処理することで実行されます。
そのオペコードを目視で確認できるようにしてしまうのがこちらのモジュールです。
PHPのソースコードを読み込んで、変換後のオペコードをvar_dumpのような形式で表示します。
一体どんな需要があってこんなものが作られたのだろう。

PHPカンファレンス2014で発表のあった「コアから読み解くPHP5.5」では実行速度の話の流れでオペコードを確認していました。
このように自分のソースコードをオペコードレベルで確認することで、遅さの原因が分かる方もいるのかもしれません。
少なくとも自分はわかりません。

6. Yet Another Framework

http://php.net/manual/ja/book.yaf.php

なぜ突然フレームワークの話なのか。
実はこれ、「その他の基本モジュール」に含まれている、__全てExtensionで書かれたフレームワーク__なのです。
どこかで似たような話を聞いたことがあるって? Phalcon? 知らない子ですね?

こちらは最近話題のPhalconより1年も早く開発が開始されていたフレームワークで、
公式サイトではPhalconより高速に動くぜ!と謳われています。
ちゃっかりLaravelもdisっているあたり業が深い。

内容はMVCを構成する部品と、それらを繋ぎ合わせるフロントコントローラが用意されているだけのシンプルな構成です。
公式リファレンスを読むだけでは、どう使えば良いのかといった指針がいまいち見えてきません。
GitHubにZend Frameworkの構成を真似たサンプルがあったので、とりあえず触ってみたい方はこちらをオススメします。
warmans / Yaf-PHP-Example

最後に

今回は「その他の基本モジュール」から面白そうなものを幾つか紹介してみましたが、
PHP公式リファレンスの闇は更に深く、正直、リファレンス右側のナビ(PC)の「数学」以下は全て闇です。

闇を呼び替えると、自分が理解しきれていない領域と言います。
これらを精査していくと、自分にとって有益な思いがけない発見があるかもしれません。
公式リファレンスは積極的に読んでいきましょう。

明日はtomzohさんです、宜しくお願い致します!

181
176
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
181
176

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?