PECL/perl モジュールがあるじゃないか。ずっと前から見かけてたけれど、そういえば触ったことがない。
PECL/perlを使えば、PHPにPerlのRun timecompiler+VM機能(いわゆるperlコマンド)が実装されるらしい。これを使ってみよう。PECLはドキュメントが少ないので参考にUsing Perl Code from PHP(Zend Developer Zone)を読んでみた。サイトによるとPECL/perlが出来ることは次の通り。
- load and execute perl files #Perlをロードして実行出来る
- evaluate perl code #Perlのソースをeval出来る
- access perl variables #Perlの変数をさわれる
- call perl functions #Perlの関数にアクセスできる
- instantiate perl objects #Perlのオブジェクトをインスタンス化出来る
- access properties of perl objects #PerlのPropertiesを扱える
- call methods of perl objects #Perlのオブジェクトメソッドを扱える
JSONやYAMLでPerlとデータやり取りよりも便利かも。
まずは。インストール。Perlの開発ライブラリが必要でした。テスト環境はubuntu6.10.ja desktopです
> aptitude install libperl-dev > pear install pecl/perl #ビルドできたら、phpにperl.soを組み込むように設定する > vim /etc/php5/cli/php.ini #consoleからテストするのでperl.soを組み込む > vim /etc/php5/apache2/php.ini #Webページでも使いたいたいので
早速使ってみました.
まず最初に、PHPからPLファイルを読み込んで実行してみました。
<?php print "Hello from PHP!\n"; #PHPから出力 $perl = new Perl(); #Perlをオブジェクト化 $perl->require("test01.pl"); #Perlのファイルを読み込んでEval print "Bye\n"; ?>
Perl:test01.pl
print "Hello World from Perl!!!\n"
実行すると
>php tst.01.php >Hello from PHP! >Hello World from Perl!!! >Bye
なるほど。PerlもPHPもスクリプト言語なのでEvalが出来るのですね。
test03.php
<?php ob_start(); $perl = new Perl(); $perl->require("test01.pl"); print "Hello From php\n"; $perl = new Perl();$perl->eval('print "Hello From Perl \n"'); print "Bye!!\n";
これでsystem()やshell_exec()使わなくても済みそうです。
PerlのライブラリもPHPに取り込んでしまえるそうです。
ZEの記事によると、Perlライブラリもまるごと使えるようです。PerlのDigest::MD5::md5_hexを使う例を試した。
元になるPerlコードはこんな感じ。これを元にPHP側で動的に作ってみよう。
use strict; #strict動作 use Digest::MD5 qw(md5_hex); #MD5からmd5_hex関数をGlobal空間へ md5_hex('Hello'); Digest::MD5::md5_hex("Hello");
このPLをPHPから動的に作るようにするとこんな感じになりました。
<?php //phpとperlのmd5関数の結果を比較する $perl = new Perl(); $perl->eval('use strict;'); $perl->eval('use Digest::MD5 qw(md5_hex);'); echo "PHP: "; var_dump(md5('Hello')); echo "perl: "; var_dump($perl->eval('md5_hex("Hello");')); //eval以外の呼び出し方 var_dump($perl->md5_hex("Hello")); var_dump($perl->{"Digest::MD5::md5_hex"}("Hello")); ?>
メソッド呼び出しが特殊。
変数$perlのメソッド名が便利そうですね。PHPの可変関数と可変変数使うようです。これは知ってないと理解できないかもしれない。可変変数&可変変数はPHPマニュアルにも載っていますし。Pearの抽象化ライブラリのソースで見かけることもありました。可変関数や可変変数は特殊メソッド __set/__get , __callと一緒に使うと嬉しい気分。call_uer_funcよりはマシなのではないでしょうか。
##可変関数の例## $method_name = "getName"; $object->getName() $object->$method_name( $val ); $objtct->{"getName"}() ##可変変数の例## $member_name = "ユーザー名"; echo $object->$member_name; echo $object->{"ユーザー名"};//文字コードに依らず日本語変数名が出来た echo $object->ユーザー名; //文字コードによっては日本語変数名が可能
hashとArrayとVariable
Perlには$a,%a,@a, があるけれど、phpには$aしかない。なのでPHPは型の指定をしてやる必要がある。そうしないとPerlオブジェクトはinterpreter中のドコに変数を探しに行けばいい分からない。
$perl->a; //$aを探しに行く $perl->array->a; //@aを探しに行く $perl->hash->a; //%aを探しに行く #phpからは$aで指定するけど、Perlでは$a ,%a, @a の三つの候補があるので区別をつける
Perlのエラーを補足する。例外はPerl::evalやPerl::requireでThrowされる。メッセージにSyntaxエラーとか書いてある。
evalでエラー起こしてみた。
PHP: start php #デバッグ用にphpからecho しているメッセージ PHP: eval step start #デバッグ用にphpからecho しているメッセージ Fatal error: Uncaught exception 'PerlException' with message '[perl] eval error: syntax error at (eval 1) line 2, at EOF ' in /var/test03.php:6 Stack trace: #0 /var/test03.php(6): Perl->eval('$a=$s{$d}.') #1 {main} thrown in /var/test03.php on line 6