A bridge between php and ruby

Post on 15-May-2015

6.281 views 1 download

description

2013/01/13 Tokyo Ruby Kaigi 10

Transcript of A bridge between php and ruby

PHP と

Ruby の

架け橋 2013/01/13

Tokyo Ruby Kaigi 10

do_aki

@do_aki

http://do-aki.net/

About 2 extensions

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

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

https://github.com/do-aki/php-ext-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!

Web Application?

sinatra on ext-ruby <?php

// php.ini : extension=ruby.so

ruby_require(‘sinatra’);

ruby_eval(<<<EOS

get ‘/’

‘Hello sinatra in PHP!’

end

EOS

);

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

);

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

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

);

突然の死 (Segmentation fault)

次回作にご期待ください

• 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

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

);

php_embed (rubygems.org)

https://rubygems.org/gems/php_embed

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!

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

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

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

Web Application?

sorry……

PHP Architecture

Web Server

or

OS SAPI

Zend Engine

Extensions

PHP Script

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

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

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

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

Just for Fun

Difference between PHP and Ruby

in extensions

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

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

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

Garbage Collection

zval

reference counting

+ circular reference collector

VALUE

mark and sweep (conservative)

easy handling difficulty handling

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);

rb_eval_string (Ruby)

define:

VALUE rb_eval_string(const char *str);

example:

char *code = “value=1”;

VALUE ret;

ret = rb_eval_string(code);

Build extensions

PHP

m4 macros

autoconf

Ruby

Ruby script

mkmf library

$ phpize $ configure $ make $ make install

$ ruby extconf.rb $ make $ make install

Code Reading

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

cgdb http://cgdb.github.com/

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

Commit log

Conclusion

処理系/拡張 いじるの

めっさ楽しい!

Thank you!

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

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

@do_aki