RubyからPHPをネイティブ連携させるRuby extension「php_vm」を作った

RubyからPHPのクラスとかをネイティブに呼び出すRuby extension「php_vm」を作った。
 
百聞は一見に如かず。
なんということでしょう、PHPで定義したクラスがRubyのクラスのようにインスタンス化したりメソッドを呼んだり出来るではありませんか。
 

Source
#!/usr/bin/ruby

require "php_vm"

PHPVM.exec <<EOS
class HelloClass
{
	public function __construct($name)
	{
		$this->name = $name;
	}


	// instance

	public function instanceGetHello()
	{
		return "Hello {$this->name}!!";
	}

	public function instanceSayHello()
	{
		var_dump($this->instanceGetHello());
	}


	// static

	public static function staticGetHello($name)
	{
		return "Hello {$name}!!";
	}

	public static function staticSayHello($name)
	{
		var_dump(self::staticGetHello($name));
	}
}
EOS

HelloClass = PHPVM::get_class("HelloClass")

puts "[class]"
puts HelloClass
puts HelloClass.name
puts ""

puts "[instance method]"
h = HelloClass.new("instance world")
h.instanceSayHello
p h.instanceGetHello
puts ""

puts "[static method]"
HelloClass.staticSayHello("static world")
p HelloClass.staticGetHello("static world")

 

Output
[class]
#<PHPVM::PHPClass:0x00000001c158d0>
HelloClass

[instance method]
string(22) "Hello instance world!!"
"Hello instance world!!"

[static method]
string(20) "Hello static world!!"
"Hello static world!!"

 
その他のサンプルは以下を。
https://github.com/yoshida-eth0/ruby-php_vm/tree/master/sample
 

Install

もしPHPのsapi/embedが入っていない場合、まずはPHPを手動インストール。

$ git clone git://github.com/php/php-src.git
$ cd php-src
$ ./buildconf
$ ./configure --prefix=/usr/local --enable-embed=shared --disable-cli --disable-cgi --without-pear
$ make
$ sudo make install

prefixに応じて(今回の場合は /usr/local/lib/ に)動的ライブラリにパスを通す。

$ export LD_LIBRARY_PATH=/usr/lib:/usr/local/lib

php_vmをgemで一発インストール。

$ gem install php_vm

 

動作確認

OS: Debian wheezy/sid 64bit
Ruby: 1.9.3 p194
PHP: 5.4.9
 

Thanks

do-akiさん作のphp_embed(MIT LICENSE)の、zval(PHP)からVALUE(Ruby)への変換部分を使わせて頂きました。
インストール方法はoasynnoumさんの記事を参考にさせて頂きました。
 
do-aki/php_embed · GitHub
https://github.com/do-aki/php_embed
 
RubyPHP を使ってみる。 - gem install php_embed - 壊れたメガネ
http://oasynnoum.hatenablog.com/entry/2012/10/18/102055