php: 2008年4月アーカイブ

第32回PHP勉強会に参加してきました。

LT枠でこの前作ったARGFを紹介させてもらいました。
codereposにあげてあるので、よろしかったらどうぞ!!

ARGF

発表に使った資料を公開しておきます。

Read this doc on Scribd: argf

ちなみにデモで使ったphshもcodereposで絶賛公開中でございます。
こちらも、よろしかったらどうぞ!!

phsh

rubyのライブラリとかで、ファイルの最後に次のような感じになってるものがある。

if __FILE__ == $0
  ...
end

こういう風に書いておくと、他のファイルからインクルードした場合はライブラリの機能だけ提供するんだけど、そのライブラリ自体を直接単体のスクリプトとして実行できるようにもなる。
でもこれはスクリプトとして使われることを意図してなくて、単なるサンプルプログラムとして提供されています。
これ結構便利なんですよね。
簡単なライブラリの使い方がすぐに分かるし、ちょっとお試しで使ってみるのも簡単にできる。
ドキュメント読むよりも、プログラム見た方が早いし。
でも、PHPでやってるのはあんまりみないな。

理由: コマンドラインを活用するPHPプログラマが少ない?

偏見かもしれないけど、コマンドラインを活用しているPHPプログラマが他言語と比較して相対的に少ない気がする。
コマンドラインが必要ないことをメリットにしているプロジェクトもあるし...。
Webアプリ用の言語なのでしょうがないのかな。
コマンドライン便利だけどね。

理由: PHPではargvを取得する簡便な方法がない

PHPではargvを取得する方法が3つもある。

  • $argv
  • $_SERVER['argv']
  • $GLOBALS['HTTP_SERVER_VARS']['argv']

もともとWebアプリ用の言語だからargvなんてのは後付けなんだろうけど、せめて統一して欲しかった...
PEARのConsole_Getoptでも、argvを取得する専用のメソッドが定義されている。
拙作のARGFでも専用のメソッド作りましたよ。

PHPでもやろうよ

こんな感じで簡単にできるよ。
argvの取得は$argvだけで。面倒だから。

if (isset($argv[0]) && __FILE__ === realpath($argv[0])) {
    /* sample code */
}

PHP4,5両対応のライブラリを書こうと思った時にどうしても気になるのがE_STRICTの設定。
PHP4でも動くようにプログラムを書くと、PHP5でE_STRICTを有効にした場合に警告の嵐が orz。

プログラムを分ける

そもそもプログラムを分ければ問題なさそう。
ってこれは面倒くさいすぎるので却下。

一時的にE_STRICTを無効にする

一時的にE_STRICTを無効にすればいいんじゃないだろうか。
プログラムの最初でE_STRICTをoff。

// disable E_STRICT temporary
if (defined('E_STRICT')) {
    $_original_e_strict = ini_get('error_reporting') & E_STRICT;
    ini_set('error_reporting', ini_get('error_reporting') & ~E_STRICT);
}

プログラムの最後で元の設定に戻す。

// get E_STRICT setting back
if (defined('E_STRICT')) {
    ini_set('error_reporting', ini_get('error_reporting') | $_original_e_strict);
}

途中で他のファイルをincludeしなければこれでいけそう。

ARGFとは

rubyで使える機能で、入力を抽象化してくれます。
ARGFを使うとフィルタプログラムのようなコマンドラインプログラムが簡単に書けます。

ARGF

これ、とっても便利でrubyでプログラム書くときは(知らずに)よく使います。
ARGFを使うと入力が標準入力だろうが、ファイルが引数で複数渡されようが、プログラムを全く変更しないで動作させることができます。

% vim cat.rb    # cat と同じプログラム
ARGF.each {|line| print line}    # 本当はもっと簡単に書ける
% ruby cat.rb < cat.rb    # 標準入力から
% ruby cat.rb foo.txt bar.txt    # 引数に複数ファイル渡しても大丈夫

phpでは

コマンドラインのプログラムが書きづらい。 ><
もともとweb用の言語なので、しょうがないといえばしょうがないかもしれない。
とはいえ、phpのプロジェクトをやってるとコマンドラインのプログラムもphpで書くわけです。

php用ARGF作った

php用のARGFを作ってみました。
php4, php5両方で動きます。
codereposにコミットしました。

ARGF

サンプル

% vim cat.php    # catと同じプログラム
each()) {
    echo $line;
}
% php cat.php < cat.php    # 標準入力から
% php cat.php foo.txt bar.txt    # 引数に複数ファイル渡しても大丈夫

使い方

require_once('ARGF.php');

ファイルをインクルードすると$ARGC, $ARGV, $ARGFが定義されます。

$ARGC

コマンドラインの引数の数になります。
ARGF::ARGC(); でも取り出せます。

$ARGV

コマンドラインの引数の配列になります。
ARGF::ARGV(); でも取り出せます。

$ARGF

メインのオブジェクトです。
他の関数の中とかスコープが閉じたところで使いたい場合は、適当にインスタンスを取り出してあげてください。

$ARGF = new ARGF();
$ARGF = ARGF::getInstance();

$ARGF->each()

一行ずつ取り出します。

$ARGF->toArray()

全ての入力を一行ずつの配列に変換します。

$ARGF->toString()

全ての入力を一つの文字列に変換します。

$ARGF->line

現在読み込んでる仮想的な行番号を示します。

$ARGF->filename

現在処理しているファイル名を示します。

まとめ

ARGFを使うとコマンドラインのプログラム書くのが楽になるよ!!

実はちょっと前に飲み会から帰ってきて勢いで作ったんだけど、せっかくだからcodereposに公開。

このアーカイブについて

このページには、2008年4月以降に書かれたブログ記事のうちphpカテゴリに属しているものが含まれています。

前のアーカイブはphp: 2008年3月です。

次のアーカイブはphp: 2008年5月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。