Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Php in ruby

  • Login to see the comments

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?

×