SlideShare a Scribd company logo
PHP   in    Ruby
             2012/09/01
           闇PHP勉強会
                 do_aki
@do_aki

http://do-aki.net/
Php in ruby
概要
Php in ruby
Php in ruby
Ruby on PHP sample (PHP Script)
<?php

ruby_eval(<<<'EOC'
 def hello_ruby_on_php
   "HELLO Ruby on PHP!!!"
 end
EOC
);

echo ruby_eval('hello_ruby_on_php()');
Ruby on PHP の 構造
php script


   php-extension


            libruby
反転させてみた
RubyscriptPHP の 構造
ruby   on



    ruby-extension

embed
 SAPI         libphp5
php_embed sample (Ruby Script)
# encoding: UTF-8
require 'php_embed'

p PhpEmbed.eval('1')              #1
p PhpEmbed.eval('true')           # true
p PhpEmbed.eval('null')           # nil
p PhpEmbed.eval('array(1,2,3)')   # [1, 2, 3]
導入
Install
1. php-embed SAPI を用意
  – コンパイル                            CentOS6

  – OS Package (php-embedded / php-devel)
2. ruby 1.9 環境
  – 1.8 では動きません
  – rbenv/ruby-builid が便利
3. gem install php-embed
php-embed SAPI
• ./configure --enable-embed=shared (or static)

• Windows 版もある

• 開発止まってる……?

php-build 使ってる場合は
PHP_BUILD_CONFIGURE_OPTS=‘--enable-embed’
で指定しましょー
ruby 1.9
• OS 標準はだいたい 1.8

• rbenv / ruby-build 使えば導入は簡単
 – https://github.com/sstephenson/rbenv
 – https://github.com/sstephenson/ruby-build
ruby 1.9 構築手順
$ cd
$ git clone git://github.com/sstephenson/rbenv.git .rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >>
~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

# ここで再ログイン

$ mkdir -p ~/.rbenv/plugins
$ cd ~/.rbenv/plugins
$ git clone git://github.com/sstephenson/ruby-build.git

$ rbenv install 1.9.3-p194


                                           readme に書いてあるけどね
gem install php-embed
• gem : Ruby のパッケージ管理ツール
 – 1.9 からは標準
 – rubygems.org
 – Pure Ruby or C拡張 関係ないみたい


• bundler で超簡単にライブラリ公開
PHP Programming (in Ruby)
# encoding: UTF-8
require 'php_embed'

p PhpEmbed::VERSION
p PhpEmbed.call('phpversion')

p PhpEmbed.call(‘array_intersect’, [1,2,3],
[2,3,4]) # [2,3]
深部
php-embed の簡単な使い方
#include <sapi/embed/php_embed.h>

int main(int argc, char* argv[]) {
   PHP_EMBED_START_BLOCK(argc, argv);
   zend_eval_string(
      "echo 'Hello Embeded PHP Workd';"
      , NULL, (char*)"Embeded PHP" TSRMLS_CC
   );
         PHP_EMBED_END_BLOCK();
         return 0;
}
// gcc sample.c –lphp5
zend_eval_stringl
• php code を実行
  – create_function / preg / ereg で使われてる
• 第3引数 retval_ptr
  – NULL  -> そのまま実行
  – 非NULL -> “return” と “;” で囲んで実行
• zend_compile_string (= compile_string)
  – Zend/zend_language_scanner.c
• zend_execute (=dtrace_execute or execute)
  – Zend/zend_dtrace.c
  – Zend/zend_vm_execute.h
PHP_EMBED_START(END)_BLOCK
• マクロ
• ZTS (Zend Thread Safety) の有無で分岐

• php_embed_init
• try – catch
• php_embed_shutdown
PHP_EMBED_*_BLOCK を展開(非ZTS)
int main(int argc, char* argv[])
{
      php_embed_init(argc, argv);
      zend_first_try {
             zend_eval_string(...)
      } zend_catch {

      } zend_end_try();
      php_embed_shutdown(TSRMLS_C);

      return 0;
}
さらに展開
php_embed_init(argc, argv);
EG(bailout)=NULL;
{
       JMP_BUF *__orig_bailout = EG(bailout);
       JMP_BUF __bailout;

      EG(bailout) = &__bailout;
      if (SETJMP(__bailout)==0) {
               zend_eval_string(...)
      } else {
               EG(bailout) = __orig_bailout;
      }
      EG(bailout) = __orig_bailout;
}
php_embed_shutdown(TSRMLS_C);
出力のハンドリング
static int php_ub_write(const char *str, unsigned int
str_length TSRMLS_DC) { return str_length }

static void php_log_message(char *message) {}

static void php_sapi_error(int type, const char *fmt, ...) {}


php_embed_module.ub_write = php_ub_write;
php_embed_module.log_message = php_log_message;
php_embed_module.sapi_error = php_sapi_error;
zval と VALUE
• zval                    構造体
  – php の内部表現
  – _zval_struct 構造体
  – = zvalue_value 構造体+ リファレンスカウンタ

• VALUE                  ポインタ
  – ruby の内部表現
  – ポインタと同じサイズを持つ unsigned な整数
  – RVALUE 構造体が実体 (FIXNUM を除いて)
TYPE(VALUE)
•   T_NONE          •   T_FILE
•   T_NIL           •   T_FIXNUM
•   T_OBJECT        •   T_TRUE
•   T_CLASS         •   T_FALSE
•   T_ICLASS        •   T_DATA
•   T_MODULE        •   T_MATCH
•   T_FLOAT         •   T_SYMBOL
•   T_STRING        •   T_RATIONAL
•   T_REGEXP        •   T_COMPLEX
•   T_ARRAY         •   T_UNDEF
•   T_HASH          •   T_NODE
•   T_STRUCT        •   T_ZOMBIE
•   T_BIGNUM
Z_TYPE (zval)
•   IS_NULL
•   IS_LONG
•   IS_DOUBLE
•   IS_BOOL
•   IS_ARRAY
•   IS_OBJECT
•   IS_STRING
•   IS_RESOURCE
•   IS_CONSTANT
•   IS_CONSTANT_ARRAY
•   IS_CALLABLE
相互変換
• それぞれの最終的な内部表現に応じて変
  換
• いずれも 言語が用意しているマクロや関
  数を介して操作

• まだ対応してない型も多い
• RESOURCE 型は難しいかもね
嵌ったこと
• Ruby 側も、setjmp / longjmp を使っている
  らしい
• 入れ子状態によってはコアダンプ
最後に
• ruby から php のコードを実行できるライ
  ブラリを作りました

• もうちょいきちんと作り込んで PHP
  Conference 2012 で発表するつもり
1




Questions?

More Related Content

PPTX
php-src の歩き方
PPTX
PHP と SAPI と ZendEngine3 と
PPTX
php7's ast
PPTX
PHP AST 徹底解説
PPTX
php and sapi and zendengine2 and...
PPTX
PHP AST 徹底解説(補遺)
PDF
最近の PHP の話
PDF
OPcache の最適化器の今
php-src の歩き方
PHP と SAPI と ZendEngine3 と
php7's ast
PHP AST 徹底解説
php and sapi and zendengine2 and...
PHP AST 徹底解説(補遺)
最近の PHP の話
OPcache の最適化器の今

What's hot (20)

PDF
OPcacheの新機能ファイルベースキャッシュの内部実装を読んでみた
PDF
Hello, C++ + JavaScript World! - Boost.勉強会 #11 東京
PDF
JIT のコードを読んでみた
PPTX
signal の話 或いは Zend Signals とは何か
PPTX
PHPとシグナル、その裏側
PDF
PECL operator で演算子オーバーロード
PDF
PHPの今とこれから2014
PDF
PECL を数えてみた
PDF
PDF
Hack/HHVM 入門
PPT
about Thrift
PDF
Task Spooler を試した
PDF
PHP の GC の話
PDF
実"戦"CakePHP Plugin
PDF
Boost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
PPTX
BoostAsioで可読性を求めるのは間違っているだろうか
PDF
CodeIgniter入門
PDF
emc++ chapter32
PDF
Windows で拡張モジュールをビルドしてみた
PDF
Good Parts of PHP and the UNIX Philosophy
OPcacheの新機能ファイルベースキャッシュの内部実装を読んでみた
Hello, C++ + JavaScript World! - Boost.勉強会 #11 東京
JIT のコードを読んでみた
signal の話 或いは Zend Signals とは何か
PHPとシグナル、その裏側
PECL operator で演算子オーバーロード
PHPの今とこれから2014
PECL を数えてみた
Hack/HHVM 入門
about Thrift
Task Spooler を試した
PHP の GC の話
実"戦"CakePHP Plugin
Boost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
BoostAsioで可読性を求めるのは間違っているだろうか
CodeIgniter入門
emc++ chapter32
Windows で拡張モジュールをビルドしてみた
Good Parts of PHP and the UNIX Philosophy
Ad

Viewers also liked (6)

PDF
20111206 GLT vol.40
PDF
ゆるLTのススメ+α
KEY
闇RubyKaigi
KEY
JoJoに学ぶプログラマが知るべきたった一つのこと
PDF
Over The Rainbow
PDF
moon and strategy
20111206 GLT vol.40
ゆるLTのススメ+α
闇RubyKaigi
JoJoに学ぶプログラマが知るべきたった一つのこと
Over The Rainbow
moon and strategy
Ad

Similar to Php in ruby (20)

PPTX
php in ruby
PPTX
20111029 rubyon php
PDF
PHP で実行中のスクリプトの動作を下から覗き見る
PDF
人類の役に立たないDSL、そしていつからRubyが最高の言語だと錯覚してた? with PHP
PDF
Modern PHP Programming @ PFI Seminar
PDF
YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情
PPTX
詳説ぺちぺち
PDF
はじめてのPHP
PPTX
PHP基礎勉強会
PDF
徹底攻略!PHP5.4
PDF
Pの付く言語の話
PDF
PHP初心者セッション2023 〜ChatGPT時代の簡単な始め方〜
PDF
PHPの今とこれから2019
PDF
PHPの今とこれから2021
PDF
PHPの今とこれから 2013
PDF
スクリプト言語PHP攻略法
PPT
PHP, Now and Then 2011
PDF
PHPの今とこれから2023
PPTX
Immortal
PDF
お前は PHP の歴史的な理由の数を覚えているのか
php in ruby
20111029 rubyon php
PHP で実行中のスクリプトの動作を下から覗き見る
人類の役に立たないDSL、そしていつからRubyが最高の言語だと錯覚してた? with PHP
Modern PHP Programming @ PFI Seminar
YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情
詳説ぺちぺち
はじめてのPHP
PHP基礎勉強会
徹底攻略!PHP5.4
Pの付く言語の話
PHP初心者セッション2023 〜ChatGPT時代の簡単な始め方〜
PHPの今とこれから2019
PHPの今とこれから2021
PHPの今とこれから 2013
スクリプト言語PHP攻略法
PHP, Now and Then 2011
PHPの今とこれから2023
Immortal
お前は PHP の歴史的な理由の数を覚えているのか

More from do_aki (20)

PPTX
Tritonn から Elasticsearch への移行話
PPTX
再考:列挙型
PPTX
Writing php extensions in golang
PPTX
N対1 レプリケーション + Optimizer Hint
PPTX
20150212 プレゼンテーションzen
PPTX
MySQL Casual Talks 7 「N:1 レプリケーション ~進捗どうですか?~」
PPTX
20141017 introduce razor
PPTX
20141011 mastering mysqlnd
PPTX
PHP から Groonga を使うにはこんなコードになるよ!
PPTX
N:1 Replication meets MHA
PDF
Php radomize
PPTX
セキュアそうでセキュアじゃない少しセキュアな気分になれるmysql_config_editor
PPTX
マスタN対スレーブ1レプリケーションの作り方 ~あれから~
PPTX
Excel is image viewer
PDF
A bridge between php and ruby
PDF
Ruby and comparison_and...php
PPTX
Sore php
PPTX
Ruby enumerable source code reading
PPTX
続マスタN対スレーブ1レプリケーションの作り方
PPTX
Mod lua
Tritonn から Elasticsearch への移行話
再考:列挙型
Writing php extensions in golang
N対1 レプリケーション + Optimizer Hint
20150212 プレゼンテーションzen
MySQL Casual Talks 7 「N:1 レプリケーション ~進捗どうですか?~」
20141017 introduce razor
20141011 mastering mysqlnd
PHP から Groonga を使うにはこんなコードになるよ!
N:1 Replication meets MHA
Php radomize
セキュアそうでセキュアじゃない少しセキュアな気分になれるmysql_config_editor
マスタN対スレーブ1レプリケーションの作り方 ~あれから~
Excel is image viewer
A bridge between php and ruby
Ruby and comparison_and...php
Sore php
Ruby enumerable source code reading
続マスタN対スレーブ1レプリケーションの作り方
Mod lua

Php in ruby

  • 1. PHP in Ruby 2012/09/01 闇PHP勉強会 do_aki
  • 7. Ruby on PHP sample (PHP Script) <?php ruby_eval(<<<'EOC' def hello_ruby_on_php "HELLO Ruby on PHP!!!" end EOC ); echo ruby_eval('hello_ruby_on_php()');
  • 8. Ruby on PHP の 構造 php script php-extension libruby
  • 10. RubyscriptPHP の 構造 ruby on ruby-extension embed SAPI libphp5
  • 11. php_embed sample (Ruby Script) # encoding: UTF-8 require 'php_embed' p PhpEmbed.eval('1') #1 p PhpEmbed.eval('true') # true p PhpEmbed.eval('null') # nil p PhpEmbed.eval('array(1,2,3)') # [1, 2, 3]
  • 13. Install 1. php-embed SAPI を用意 – コンパイル CentOS6 – OS Package (php-embedded / php-devel) 2. ruby 1.9 環境 – 1.8 では動きません – rbenv/ruby-builid が便利 3. gem install php-embed
  • 14. php-embed SAPI • ./configure --enable-embed=shared (or static) • Windows 版もある • 開発止まってる……? php-build 使ってる場合は PHP_BUILD_CONFIGURE_OPTS=‘--enable-embed’ で指定しましょー
  • 15. ruby 1.9 • OS 標準はだいたい 1.8 • rbenv / ruby-build 使えば導入は簡単 – https://github.com/sstephenson/rbenv – https://github.com/sstephenson/ruby-build
  • 16. ruby 1.9 構築手順 $ cd $ git clone git://github.com/sstephenson/rbenv.git .rbenv $ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile $ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile # ここで再ログイン $ mkdir -p ~/.rbenv/plugins $ cd ~/.rbenv/plugins $ git clone git://github.com/sstephenson/ruby-build.git $ rbenv install 1.9.3-p194 readme に書いてあるけどね
  • 17. gem install php-embed • gem : Ruby のパッケージ管理ツール – 1.9 からは標準 – rubygems.org – Pure Ruby or C拡張 関係ないみたい • bundler で超簡単にライブラリ公開
  • 18. PHP Programming (in Ruby) # encoding: UTF-8 require 'php_embed' p PhpEmbed::VERSION p PhpEmbed.call('phpversion') p PhpEmbed.call(‘array_intersect’, [1,2,3], [2,3,4]) # [2,3]
  • 20. php-embed の簡単な使い方 #include <sapi/embed/php_embed.h> int main(int argc, char* argv[]) { PHP_EMBED_START_BLOCK(argc, argv); zend_eval_string( "echo 'Hello Embeded PHP Workd';" , NULL, (char*)"Embeded PHP" TSRMLS_CC ); PHP_EMBED_END_BLOCK(); return 0; } // gcc sample.c –lphp5
  • 21. zend_eval_stringl • php code を実行 – create_function / preg / ereg で使われてる • 第3引数 retval_ptr – NULL -> そのまま実行 – 非NULL -> “return” と “;” で囲んで実行 • zend_compile_string (= compile_string) – Zend/zend_language_scanner.c • zend_execute (=dtrace_execute or execute) – Zend/zend_dtrace.c – Zend/zend_vm_execute.h
  • 22. PHP_EMBED_START(END)_BLOCK • マクロ • ZTS (Zend Thread Safety) の有無で分岐 • php_embed_init • try – catch • php_embed_shutdown
  • 23. PHP_EMBED_*_BLOCK を展開(非ZTS) int main(int argc, char* argv[]) { php_embed_init(argc, argv); zend_first_try { zend_eval_string(...) } zend_catch { } zend_end_try(); php_embed_shutdown(TSRMLS_C); return 0; }
  • 24. さらに展開 php_embed_init(argc, argv); EG(bailout)=NULL; { JMP_BUF *__orig_bailout = EG(bailout); JMP_BUF __bailout; EG(bailout) = &__bailout; if (SETJMP(__bailout)==0) { zend_eval_string(...) } else { EG(bailout) = __orig_bailout; } EG(bailout) = __orig_bailout; } php_embed_shutdown(TSRMLS_C);
  • 25. 出力のハンドリング static int php_ub_write(const char *str, unsigned int str_length TSRMLS_DC) { return str_length } static void php_log_message(char *message) {} static void php_sapi_error(int type, const char *fmt, ...) {} php_embed_module.ub_write = php_ub_write; php_embed_module.log_message = php_log_message; php_embed_module.sapi_error = php_sapi_error;
  • 26. zval と VALUE • zval 構造体 – php の内部表現 – _zval_struct 構造体 – = zvalue_value 構造体+ リファレンスカウンタ • VALUE ポインタ – ruby の内部表現 – ポインタと同じサイズを持つ unsigned な整数 – RVALUE 構造体が実体 (FIXNUM を除いて)
  • 27. TYPE(VALUE) • T_NONE • T_FILE • T_NIL • T_FIXNUM • T_OBJECT • T_TRUE • T_CLASS • T_FALSE • T_ICLASS • T_DATA • T_MODULE • T_MATCH • T_FLOAT • T_SYMBOL • T_STRING • T_RATIONAL • T_REGEXP • T_COMPLEX • T_ARRAY • T_UNDEF • T_HASH • T_NODE • T_STRUCT • T_ZOMBIE • T_BIGNUM
  • 28. Z_TYPE (zval) • IS_NULL • IS_LONG • IS_DOUBLE • IS_BOOL • IS_ARRAY • IS_OBJECT • IS_STRING • IS_RESOURCE • IS_CONSTANT • IS_CONSTANT_ARRAY • IS_CALLABLE
  • 29. 相互変換 • それぞれの最終的な内部表現に応じて変 換 • いずれも 言語が用意しているマクロや関 数を介して操作 • まだ対応してない型も多い • RESOURCE 型は難しいかもね
  • 30. 嵌ったこと • Ruby 側も、setjmp / longjmp を使っている らしい • 入れ子状態によってはコアダンプ
  • 31. 最後に • ruby から php のコードを実行できるライ ブラリを作りました • もうちょいきちんと作り込んで PHP Conference 2012 で発表するつもり