それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

symfonyからPlagger呼び出したいなと。


PECL/perl モジュールがあるじゃないか。ずっと前から見かけてたけれど、そういえば触ったことがない。

PECL/perlを使えば、PHPPerlの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やYAMLPerlとデータやり取りよりも便利かも。


まずは。インストール。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:test01.php

<?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

なるほど。PerlPHPスクリプト言語なので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はアクセス出来る。

メソッド呼び出しが特殊。

変数$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