Php in ruby

2,984 views
2,829 views

Published on

Published in: Technology
1 Comment
4 Likes
Statistics
Notes
  • すごい!
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
2,984
On SlideShare
0
From Embeds
0
Number of Embeds
1,044
Actions
Shares
0
Downloads
7
Comments
1
Likes
4
Embeds 0
No embeds

No notes for slide

Php in ruby

  1. 1. PHP in Ruby 2012/09/01 闇PHP勉強会 do_aki
  2. 2. @do_akihttp://do-aki.net/
  3. 3. 概要
  4. 4. Ruby on PHP sample (PHP Script)<?phpruby_eval(<<<EOC def hello_ruby_on_php "HELLO Ruby on PHP!!!" endEOC);echo ruby_eval(hello_ruby_on_php());
  5. 5. Ruby on PHP の 構造php script php-extension libruby
  6. 6. 反転させてみた
  7. 7. RubyscriptPHP の 構造ruby on ruby-extensionembed SAPI libphp5
  8. 8. php_embed sample (Ruby Script)# encoding: UTF-8require php_embedp PhpEmbed.eval(1) #1p PhpEmbed.eval(true) # truep PhpEmbed.eval(null) # nilp PhpEmbed.eval(array(1,2,3)) # [1, 2, 3]
  9. 9. 導入
  10. 10. Install1. php-embed SAPI を用意 – コンパイル CentOS6 – OS Package (php-embedded / php-devel)2. ruby 1.9 環境 – 1.8 では動きません – rbenv/ruby-builid が便利3. gem install php-embed
  11. 11. php-embed SAPI• ./configure --enable-embed=shared (or static)• Windows 版もある• 開発止まってる……?php-build 使ってる場合はPHP_BUILD_CONFIGURE_OPTS=‘--enable-embed’で指定しましょー
  12. 12. ruby 1.9• OS 標準はだいたい 1.8• rbenv / ruby-build 使えば導入は簡単 – https://github.com/sstephenson/rbenv – https://github.com/sstephenson/ruby-build
  13. 13. 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 に書いてあるけどね
  14. 14. gem install php-embed• gem : Ruby のパッケージ管理ツール – 1.9 からは標準 – rubygems.org – Pure Ruby or C拡張 関係ないみたい• bundler で超簡単にライブラリ公開
  15. 15. PHP Programming (in Ruby)# encoding: UTF-8require php_embedp PhpEmbed::VERSIONp PhpEmbed.call(phpversion)p PhpEmbed.call(‘array_intersect’, [1,2,3],[2,3,4]) # [2,3]
  16. 16. 深部
  17. 17. 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
  18. 18. 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
  19. 19. PHP_EMBED_START(END)_BLOCK• マクロ• ZTS (Zend Thread Safety) の有無で分岐• php_embed_init• try – catch• php_embed_shutdown
  20. 20. 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;}
  21. 21. さらに展開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);
  22. 22. 出力のハンドリングstatic int php_ub_write(const char *str, unsigned intstr_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;
  23. 23. zval と VALUE• zval 構造体 – php の内部表現 – _zval_struct 構造体 – = zvalue_value 構造体+ リファレンスカウンタ• VALUE ポインタ – ruby の内部表現 – ポインタと同じサイズを持つ unsigned な整数 – RVALUE 構造体が実体 (FIXNUM を除いて)
  24. 24. 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
  25. 25. 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
  26. 26. 相互変換• それぞれの最終的な内部表現に応じて変 換• いずれも 言語が用意しているマクロや関 数を介して操作• まだ対応してない型も多い• RESOURCE 型は難しいかもね
  27. 27. 嵌ったこと• Ruby 側も、setjmp / longjmp を使っている らしい• 入れ子状態によってはコアダンプ
  28. 28. 最後に• ruby から php のコードを実行できるライ ブラリを作りました• もうちょいきちんと作り込んで PHP Conference 2012 で発表するつもり
  29. 29. 1Questions?

×