Publicidad
Publicidad

Más contenido relacionado

Publicidad
Publicidad

Último(20)

Php in ruby

  1. PHP in Ruby 2012/09/01 闇PHP勉強会 do_aki
  2. @do_aki http://do-aki.net/
  3. 概要
  4. 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()');
  5. Ruby on PHP の 構造 php script php-extension libruby
  6. 反転させてみた
  7. RubyscriptPHP の 構造 ruby on ruby-extension embed SAPI libphp5
  8. 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]
  9. 導入
  10. 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
  11. php-embed SAPI • ./configure --enable-embed=shared (or static) • Windows 版もある • 開発止まってる……? php-build 使ってる場合は PHP_BUILD_CONFIGURE_OPTS=‘--enable-embed’ で指定しましょー
  12. ruby 1.9 • OS 標準はだいたい 1.8 • rbenv / ruby-build 使えば導入は簡単 – https://github.com/sstephenson/rbenv – https://github.com/sstephenson/ruby-build
  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. gem install php-embed • gem : Ruby のパッケージ管理ツール – 1.9 からは標準 – rubygems.org – Pure Ruby or C拡張 関係ないみたい • bundler で超簡単にライブラリ公開
  15. 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]
  16. 深部
  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. 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. PHP_EMBED_START(END)_BLOCK • マクロ • ZTS (Zend Thread Safety) の有無で分岐 • php_embed_init • try – catch • php_embed_shutdown
  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. さらに展開 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. 出力のハンドリング 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;
  23. zval と VALUE • zval 構造体 – php の内部表現 – _zval_struct 構造体 – = zvalue_value 構造体+ リファレンスカウンタ • VALUE ポインタ – ruby の内部表現 – ポインタと同じサイズを持つ unsigned な整数 – RVALUE 構造体が実体 (FIXNUM を除いて)
  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. 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. 相互変換 • それぞれの最終的な内部表現に応じて変 換 • いずれも 言語が用意しているマクロや関 数を介して操作 • まだ対応してない型も多い • RESOURCE 型は難しいかもね
  27. 嵌ったこと • Ruby 側も、setjmp / longjmp を使っている らしい • 入れ子状態によってはコアダンプ
  28. 最後に • ruby から php のコードを実行できるライ ブラリを作りました • もうちょいきちんと作り込んで PHP Conference 2012 で発表するつもり
  29. 1 Questions?
Publicidad