A bridge between php and ruby

43
PHP Ruby 架け2013/01/13 Tokyo Ruby Kaigi 10 do_aki

description

2013/01/13 Tokyo Ruby Kaigi 10

Transcript of A bridge between php and ruby

Page 1: A bridge between php and ruby

PHP と

Ruby の

架け橋 2013/01/13

Tokyo Ruby Kaigi 10

do_aki

Page 2: A bridge between php and ruby

@do_aki

http://do-aki.net/

Page 3: A bridge between php and ruby

About 2 extensions

php-extension ruby Runnable ruby script in PHP (>=5.4)

php_embed gem library Runnable php script in Ruby(>= 1.9)

Page 4: A bridge between php and ruby

https://github.com/do-aki/php-ext-ruby

Page 5: A bridge between php and ruby
Page 6: A bridge between php and ruby

php-ext-ruby sample code <?php

// php.ini : extension=ruby.so

ruby_eval(<<<'EOS'

def hello

“Ruby #{RUBY_VERSION} in PHP! "

end

EOS

);

echo ruby_eval('hello()'); # Ruby 1.9.3 in PHP!

Page 7: A bridge between php and ruby

Web Application?

Page 8: A bridge between php and ruby

sinatra on ext-ruby <?php

// php.ini : extension=ruby.so

ruby_require(‘sinatra’);

ruby_eval(<<<EOS

get ‘/’

‘Hello sinatra in PHP!’

end

EOS

);

Page 9: A bridge between php and ruby

sinatra on ext-ruby (not work)

<?php

// php.ini : extension=ruby.so

ruby_require(‘sinatra’);

ruby_eval(<<<EOS

get ‘/’

‘Hello sinatra in PHP!’

end

EOS

);

Page 10: A bridge between php and ruby

ruby_require calls rb_require but…

• rb_require is ‘require’ in Ruby script

• require is not rb_require in Ruby 1.9

• rb_require(“rubygems”) already called

• rubygems override original require!

• also not work (another reason) rb_funcall(rb_mKernel, rb_intern(“require”)) ?

Page 11: A bridge between php and ruby

sinatra on ext-ruby again <?php

ruby_eval(<<<EOS

require 'sinatra/base‘

class App < Sinatra::Base

get '/' do

'Hello Sinatra in PHP!'

end

end

EOS

);

Page 12: A bridge between php and ruby

突然の死 (Segmentation fault)

Page 13: A bridge between php and ruby

次回作にご期待ください

• Runnable standard library

• ruby-mysql library runs too

• Web application works in PHP and Ruby if you make F/W which runnable on this extension!

o...rz

Page 14: A bridge between php and ruby

<?php

ruby_eval(<<<'EOC'

require 'mysql'

client = Mysql.connect('127.0.0.1', ‘usr', ‘pas’, 'test')

client.query("SELECT id,name FROM hoge").each do |id, name|

p [id, name]

end

EOC

);

Page 15: A bridge between php and ruby

php_embed (rubygems.org)

https://rubygems.org/gems/php_embed

Page 16: A bridge between php and ruby

php_embed sample code require ‘php_embed’

PhpEmbed.eval <<EOS

function hello($rv) {

$pv = phpversion();

return “PHP {$pv} in Ruby {$rv}!”;

}

EOS

retval = PhpEmbed.call(:hello, RUBY_VERSION)

p retval # PHP 5.4.10 in Ruby 1.9.3!

Page 17: A bridge between php and ruby

PhpEmbed::Value Class

• This class holds a PHP variable

• Convert Ruby variables into PHP variables (new)

• Convert PHP variables into Ruby variables (to_X)

• PHPnized comparison rule

Page 18: A bridge between php and ruby

PhpEmbed::Value sample code p_ary = PhpEmbed::Value.new([1, 2, 3])

p p_ary # Array

p p_ary.to_a # [1, 2, 3]

p p_ary.to_a[0].class # PhpEmbed::Value

---------------------------------------------------------

p_zero = PhpEmbed::Value.new(0)

p_false = PhpEmbed::Value.new(false)

p pzero == p_false # true

Page 19: A bridge between php and ruby

PhpEmbed::Value sample code func = PhpEmbed::Value.eval << EOS

function ($ary) {

return count($ary);

}

EOS

p func.class # PhpEmbed::Value

p func.callable? # true

p func.call(1..100); # 100

Page 20: A bridge between php and ruby

Web Application?

Page 21: A bridge between php and ruby

sorry……

Page 22: A bridge between php and ruby

PHP Architecture

Web Server

or

OS SAPI

Zend Engine

Extensions

PHP Script

Page 23: A bridge between php and ruby

PHP SAPIs

aolserver / apache / apache2filter /

apache2handler / apache_hooks /

caudium / cgi / cli / continuity / embed

/ fpm / isapi / litespeed / milter / nsapi

/ phttpd / pi3web / roxen / thttpd / tux

/ webjames under sapi directory in php-5.4.10 source code

Page 24: A bridge between php and ruby

PHP SAPIs

aolserver / apache / apache2filter /

apache2handler / apache_hooks /

caudium / cgi / cli / continuity / embed

/ fpm / isapi / litespeed / milter / nsapi

/ phttpd / pi3web / roxen / thttpd / tux

/ webjames under sapi directory in php-5.4.10 source code

php_embed uses embed SAPI . But embed SAPI has not interface to web server

Page 25: A bridge between php and ruby

PHP Installer

• gem install php_embed

– require “libphp5”

– yum install php-embedded php-devel

– Or compile php yourself

• gem install php_embed -- --compile-php

– compile minimal php (in gem directory)

– require gcc / tar / make

Page 26: A bridge between php and ruby
Page 27: A bridge between php and ruby

php-extension ruby Runnable ruby script in PHP (>=5.4)

php_embed gem library Runnable php script in Ruby(>= 1.9)

Page 28: A bridge between php and ruby

Just for Fun

Page 29: A bridge between php and ruby

Difference between PHP and Ruby

in extensions

Page 30: A bridge between php and ruby

Overview of PHP/Ruby extension

• Written by C language mostly

• Method(Function) in Ruby/PHP calls C Function

PHP

Ruby

Extension (C Function)

PHP

Ruby

retrun value

args

Page 31: A bridge between php and ruby

Overview of PHP/Ruby extension

PHP

Ruby

Extension (C Function)

PHP

Ruby

zval VALUE

zval VALUE

VALUE internal representation of

variable in Ruby

zval internal representation of

variable in PHP

Page 32: A bridge between php and ruby

zval VS VALUE zval

type info

+ reference count

+ value

lval (integer)

dval (floating point)

str (string)

ht (hash table)

obj (object)

VALUE

pointer (*RVALUE)

RBasic / RObject / RClass /

RFloat / RString / RArray / RRegexp / RHash … and others

or value

– false / true / nil / symbol

– same integer

– some float (>= 2.0?)

Simple Complex

Page 33: A bridge between php and ruby

Garbage Collection

zval

reference counting

+ circular reference collector

VALUE

mark and sweep (conservative)

easy handling difficulty handling

Page 34: A bridge between php and ruby

zend_eval_string (PHP) define:

ZEND_API int zend_eval_string(

char *str, zval *retval_ptr, char *string_name

TSRMLS_DC);

example:

char *code = “$value=1”, *name=“value”;

zval ret;

zend_eval_string(code, &ret, name TSRMLS_CC);

Page 35: A bridge between php and ruby

rb_eval_string (Ruby)

define:

VALUE rb_eval_string(const char *str);

example:

char *code = “value=1”;

VALUE ret;

ret = rb_eval_string(code);

Page 36: A bridge between php and ruby

Build extensions

PHP

m4 macros

autoconf

Ruby

Ruby script

mkmf library

$ phpize $ configure $ make $ make install

$ ruby extconf.rb $ make $ make install

Page 37: A bridge between php and ruby

Code Reading

Page 38: A bridge between php and ruby

GNU Global (htags) http://www.gnu.org/software/global/

Page 39: A bridge between php and ruby

cgdb http://cgdb.github.com/

Page 40: A bridge between php and ruby

References

Ruby:

RHG (Rubyソースコード完全解説)

http://i.loveruby.net/ja/rhg/

PHP :

php.net

PHP Extension Writing (PHP Quebec 2009)

http://talks.somabo.de/200903_montreal_php_extension_writing.pdf

Notice: they are old a little

Page 41: A bridge between php and ruby

Commit log

Page 42: A bridge between php and ruby

Conclusion

処理系/拡張 いじるの

めっさ楽しい!

Page 43: A bridge between php and ruby

Thank you!

英語間違えてたらこっそり教えて><

2013/01/13 Tokyo Ruby Kaigi 10 A Bridge Between PHP and Ruby

@do_aki