More Related Content Similar to Php in ruby (20) Php in ruby1. 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()');
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
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
31. 最後に
• ruby から php のコードを実行できるライ
ブラリを作りました
• もうちょいきちんと作り込んで PHP
Conference 2012 で発表するつもり