php_embed 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,2 +1,37 @@
1
- ruby-ext-php
2
- ============
1
+ php_embed
2
+ ============
3
+
4
+ Ruby 上で PHP のコードを実行します
5
+
6
+ Requirements
7
+ -----------
8
+ * ruby >= 1.9
9
+ * php embed-sapi
10
+
11
+ ruby 1.9 系でしか動きません。
12
+
13
+ コンパイル時に phpize が、
14
+ 実行に php embed-sapi 共有ライブラリが、
15
+ それぞれ必要となります。
16
+
17
+ php をソースからコンパイルする場合、そのままでは embed-sapi はコンパイルされません。
18
+ configure 時に、 --enable-embed オプションを指定してください。
19
+
20
+ CentOS6 であれば php-embeded と php-devel パッケージでも代替可能です。
21
+
22
+
23
+ Installation
24
+ -----------
25
+ 1. prepare php embed-sapi
26
+ 2. **gem install php_embed**
27
+
28
+ Usage
29
+ -----------
30
+ spec ディレクトリにある rspec を参考にしてください。
31
+
32
+
33
+ ### Slide
34
+ http://www.slideshare.net/do_aki/php-in-ruby
35
+
36
+ php-embed となっているところは php_embed の誤りです。
37
+
data/ext/php_embed/php.c CHANGED
@@ -2,6 +2,9 @@
2
2
  #include <ruby.h>
3
3
  #include <sapi/embed/php_embed.h>
4
4
 
5
+ #include <php_embed_value.h>
6
+ VALUE zval_to_value(zval* val);
7
+
5
8
  static VALUE callback_output = Qnil;
6
9
  static VALUE callback_error = Qnil;
7
10
 
@@ -29,6 +32,75 @@ static void php_sapi_error(int type, const char *fmt, ...)
29
32
  va_end(va);
30
33
  }
31
34
 
35
+ static int is_array_convertable(HashTable* ht) {
36
+ HashPosition pos;
37
+ char *string_key;
38
+ ulong num_index;
39
+ ulong index = 0;
40
+
41
+ zend_hash_internal_pointer_reset_ex(ht, &pos);
42
+ do {
43
+ switch(zend_hash_get_current_key_ex(ht, &string_key, NULL, &num_index, 0, &pos)) {
44
+ case HASH_KEY_IS_STRING:
45
+ return 0;
46
+ case HASH_KEY_NON_EXISTANT:
47
+ return 1;
48
+ case HASH_KEY_IS_LONG:
49
+ if (num_index != index) {
50
+ return 0;
51
+ }
52
+ ++index;
53
+ }
54
+ } while(SUCCESS == zend_hash_move_forward_ex(ht, &pos));
55
+ return 1;
56
+ }
57
+
58
+ static VALUE hash_to_array(HashTable* ht) {
59
+ HashPosition pos;
60
+ zval** data;
61
+ VALUE ret;
62
+
63
+ ret = rb_ary_new2(zend_hash_num_elements(ht));
64
+
65
+ zend_hash_internal_pointer_reset_ex(ht, &pos);
66
+ while (SUCCESS == zend_hash_get_current_data_ex(ht, (void **)&data, &pos)) {
67
+ VALUE t = zval_to_value(*data);
68
+ rb_ary_push(ret, t);
69
+ zend_hash_move_forward_ex(ht, &pos);
70
+ }
71
+ return ret;
72
+ }
73
+
74
+ static VALUE hash_to_hash(HashTable* ht) {
75
+ HashPosition pos;
76
+ zval** data;
77
+ VALUE ret;
78
+
79
+ ret = rb_hash_new();
80
+
81
+ zend_hash_internal_pointer_reset_ex(ht, &pos);
82
+ while (SUCCESS == zend_hash_get_current_data_ex(ht, (void **)&data, &pos)) {
83
+ char* string_key;
84
+ ulong num_index;
85
+ VALUE key = Qnil;
86
+ VALUE val = zval_to_value(*data);
87
+
88
+ switch(zend_hash_get_current_key_ex(ht, &string_key, NULL, &num_index, 0, &pos)) {
89
+ case HASH_KEY_IS_STRING:
90
+ key = rb_str_new_cstr(string_key);
91
+ break;
92
+ case HASH_KEY_IS_LONG:
93
+ key = LONG2NUM(num_index);
94
+ break;
95
+ }
96
+
97
+ rb_hash_aset(ret, key, val);
98
+ zend_hash_move_forward_ex(ht, &pos);
99
+ }
100
+ return ret;
101
+ }
102
+
103
+
32
104
  VALUE zval_to_value(zval* val) {
33
105
  VALUE r;
34
106
 
@@ -42,144 +114,139 @@ VALUE zval_to_value(zval* val) {
42
114
  case IS_DOUBLE:
43
115
  return DBL2NUM(Z_DVAL_P(val));
44
116
  case IS_ARRAY:
117
+ case IS_CONSTANT_ARRAY:
45
118
  {
46
119
  HashTable* ht = Z_ARRVAL_P(val);
47
- HashPosition p;
48
- int idx = 0;
49
- zval** data;
50
120
 
51
- r = rb_ary_new2(zend_hash_num_elements(ht));
121
+ if (0 == zend_hash_num_elements(ht)) {
122
+ return rb_ary_new();
123
+ }
52
124
 
53
- zend_hash_internal_pointer_reset_ex(ht, &p);
54
- while (zend_hash_get_current_data_ex(ht, (void **)&data, &p) == SUCCESS) {
55
- VALUE t = zval_to_value(*data);
56
- rb_ary_store(r, idx++, t);
57
- zend_hash_move_forward_ex(ht, &p);
125
+ if (is_array_convertable(ht)) {
126
+ return hash_to_array(ht);
58
127
  }
59
- return r;
128
+
129
+ return hash_to_hash(ht);
60
130
  }
61
131
  case IS_OBJECT:
62
- case IS_STRING:
63
132
  case IS_RESOURCE:
64
133
  case IS_CONSTANT:
65
- case IS_CONSTANT_ARRAY:
66
- default:
67
134
  convert_to_string(val);
135
+ case IS_STRING:
68
136
  return rb_str_new(Z_STRVAL_P(val), Z_STRLEN_P(val));
137
+ default:
138
+ return Qnil;
69
139
  }
70
140
  }
71
141
 
72
- void value2php_arg(VALUE v, char* out_arg) {
73
- switch (TYPE(v)) {
74
- case T_FALSE:
75
- strcat(out_arg, "false");
76
- return;
77
- case T_TRUE:
78
- strcat(out_arg, "true");
79
- return;
80
- case T_UNDEF:
81
- case T_NIL:
82
- strcat(out_arg, "null");
83
- return;
84
- case T_FIXNUM:
85
- {
86
- VALUE t = rb_fix2str(v, 10);
87
- strcat(out_arg, StringValuePtr(t));
88
- }
89
- return;
90
- case T_BIGNUM:
91
- {
92
- VALUE t = rb_big2str(v, 10);
93
- strcat(out_arg, StringValuePtr(t));
94
- }
95
- return;
96
- case T_FLOAT:
97
- {
98
- VALUE t = rb_funcall(v, rb_intern("to_s"), 0);
99
- strcat(out_arg, StringValuePtr(t));
100
- }
101
- return;
102
- case T_ARRAY:
103
- {
104
- int i;
105
- strcat(out_arg, "array(");
106
- for(i=0;i<RARRAY_LEN(v);++i) {
107
- value2php_arg(RARRAY_PTR(v)[i], out_arg);
108
- if (i != RARRAY_LEN(v)-1) {
109
- strcat(out_arg, ",");
110
- }
111
- }
112
- strcat(out_arg, ")");
113
- }
114
- case T_HASH:
115
- /* no implement */
116
- return;
117
- case T_STRING:
118
- default:
119
- strcat(out_arg, "'");
120
- strcat(out_arg, StringValuePtr(v));
121
- strcat(out_arg, "'");
122
- }
142
+ int eval_php_code(char* code) {
143
+ int ret = 0;
144
+
145
+ zend_try {
146
+ ret = zend_eval_string(code, NULL, (char*)"" TSRMLS_CC);
147
+ } zend_catch {
148
+
149
+ } zend_end_try();
150
+
151
+ return FAILURE == ret;
123
152
  }
124
153
 
125
- int eval_php_code(char* code, VALUE* return_value) {
126
- const char *argv[2] = {"ruby", NULL};
154
+ int eval_and_return_php_code(char* code, VALUE* return_value) {
127
155
  int err = 0;
128
- zval **data;
129
156
  zval retval;
130
157
 
131
- PHP_EMBED_START_BLOCK(1, (char**)argv);
132
-
133
- if (zend_eval_string(code, &retval, (char*)"" TSRMLS_CC) == FAILURE) {
134
- err = 1;
135
- }
158
+ zend_try {
159
+ if (zend_eval_string(code, &retval, (char*)"" TSRMLS_CC) == FAILURE) {
160
+ err = 1;
161
+ } else {
162
+ *return_value = zval_to_value(&retval);
163
+ zval_dtor(&retval);
164
+ }
136
165
 
137
- PHP_EMBED_END_BLOCK();
166
+ } zend_catch {
138
167
 
139
- *return_value = zval_to_value(&retval);
140
- zval_dtor(&retval);
168
+ } zend_end_try();
141
169
 
142
170
  return err;
143
171
  }
144
172
 
145
173
  VALUE php_eval(VALUE self, VALUE code) {
146
- VALUE retval;
147
- if (eval_php_code(StringValuePtr(code), &retval)) {
174
+ if (eval_php_code(StringValuePtr(code))) {
148
175
  rb_raise(rb_eRuntimeError, "invalid code");
149
176
  }
150
177
 
151
- return retval;
178
+ return Qnil;
152
179
  }
153
180
 
154
181
  VALUE php_call(int argc, VALUE *argv, VALUE self) {
155
- VALUE func, args, retval;
182
+ VALUE func, args, arg_str, retval;
156
183
  int i;
157
- char arg_str[1024], call_str[2048];
158
- zval* t = NULL;
184
+ char* call_str;
159
185
 
160
186
  rb_scan_args(argc, argv, "1*", &func, &args);
161
187
 
162
-
163
- arg_str[0] = '\0';
188
+ if (T_SYMBOL == TYPE(func)) {
189
+ func = rb_sym_to_s(func);
190
+ }
191
+
192
+ if (T_STRING != TYPE(func)) {
193
+ rb_raise(rb_eRuntimeError, "invalid function name");
194
+ }
195
+
196
+ arg_str = rb_str_new_cstr("");
164
197
  for(i=0; i<argc-1; ++i) {
165
- char arg[255] = "";
166
- value2php_arg(RARRAY_PTR(args)[i], arg);
167
- strcat(arg_str, arg);
198
+ VALUE r = convert_value_into_php_string(RARRAY_PTR(args)[i]);
199
+ rb_str_cat(arg_str, RSTRING_PTR(r), RSTRING_LEN(r));
168
200
 
169
201
  if (i != argc-2) {
170
- strcat(arg_str, ",");
202
+ rb_str_cat2(arg_str, ",");
171
203
  }
172
204
  }
173
205
 
174
- sprintf(call_str, "%s(%s)", StringValuePtr(func), arg_str);
175
- //printf("\n***%s***\n", call_str);
176
- if (eval_php_code(call_str, &retval)) {
206
+ call_str = malloc(RSTRING_LEN(func) + RSTRING_LEN(arg_str) + sizeof("()") + 1);
207
+ sprintf(call_str, "%s(%s)", RSTRING_PTR(func), RSTRING_PTR(arg_str));
208
+ if (eval_and_return_php_code(call_str, &retval)) {
177
209
  rb_raise(rb_eRuntimeError, "eval error");
178
- }
210
+ }
179
211
 
180
212
  return retval;
181
213
  }
182
214
 
215
+ VALUE php_run(VALUE self, VALUE file) {
216
+ VALUE retval = Qtrue;
217
+ zend_file_handle handle;
218
+
219
+ if (T_STRING != TYPE(file)) {
220
+ rb_raise(rb_eRuntimeError, "file must be string");
221
+ }
222
+
223
+ handle.type = ZEND_HANDLE_FILENAME;
224
+ handle.filename = RSTRING_PTR(file);
225
+ handle.opened_path = NULL;
226
+ handle.free_filename = 0;
227
+
228
+ zend_try {
229
+ zend_execute_scripts(ZEND_REQUIRE TSRMLS_CC, NULL, 1, &handle);
230
+ } zend_catch {
231
+ retval = Qfalse;
232
+ } zend_end_try();
233
+
234
+ return retval;
235
+
236
+ }
237
+
238
+ VALUE php_fetch_variable(VALUE self, VALUE name) {
239
+ zval *data = NULL;
240
+ if (FAILURE == zend_hash_find(&EG(symbol_table), StringValuePtr(name), RSTRING_LEN(name), (void **)&data)) {
241
+ /* Name not found in $GLOBALS */
242
+ }
243
+ if (data == NULL) {
244
+ /* Value is NULL (not possible for symbol_table?) */
245
+ }
246
+
247
+ return Qnil;
248
+ }
249
+
183
250
  VALUE php_set_output_handler(VALUE self, VALUE callback) {
184
251
  if (rb_obj_is_proc(callback)) {
185
252
  callback_output = callback;
@@ -200,21 +267,49 @@ VALUE php_set_error_handler(VALUE self, VALUE callback) {
200
267
  return Qnil;
201
268
  }
202
269
 
270
+ void initialize_php_embed() {
271
+ const char *argv[2] = {"ruby", NULL};
272
+ php_embed_init(1, (char**)argv);
273
+ EG(bailout)=NULL;
274
+ }
275
+
276
+ void shutdown_php_embed() {
277
+ php_embed_shutdown(TSRMLS_C);
278
+ }
279
+
280
+ VALUE mPhpEmbed;
281
+
203
282
  Init_php() {
204
283
 
205
- VALUE cPhp;
206
- cPhp = rb_define_module("PhpEmbed");
207
- //rb_define_const(cPhp, "VERSION", rb_ary_new3(3, INT2FIX(0), INT2FIX(0), INT2FIX(1)));
284
+ mPhpEmbed = rb_define_module("PhpEmbed");
285
+
286
+ init_php_value();
208
287
 
209
- rb_define_singleton_method(cPhp, "eval", php_eval, 1);
210
- rb_define_singleton_method(cPhp, "call", php_call, -1);
211
- rb_define_singleton_method(cPhp, "setOutputHandler", php_set_output_handler, 1);
212
- rb_define_singleton_method(cPhp, "setErrorHandler", php_set_error_handler, 1);
288
+ //rb_define_const(mPhpEmbed, "VERSION", rb_ary_new3(3, INT2FIX(0), INT2FIX(0), INT2FIX(1)));
289
+
290
+ rb_define_singleton_method(mPhpEmbed, "eval", php_eval, 1);
291
+ rb_define_singleton_method(mPhpEmbed, "call", php_call, -1);
292
+ rb_define_singleton_method(mPhpEmbed, "run", php_run, 1);
293
+ rb_define_singleton_method(mPhpEmbed, "fetchVariable", php_fetch_variable, 1);
294
+ rb_define_singleton_method(mPhpEmbed, "setOutputHandler", php_set_output_handler, 1);
295
+ rb_define_singleton_method(mPhpEmbed, "setErrorHandler", php_set_error_handler, 1);
213
296
 
214
297
  php_embed_module.ub_write = php_ub_write;
215
298
  php_embed_module.log_message = php_log_message;
216
299
  php_embed_module.sapi_error = php_sapi_error;
217
300
 
301
+ initialize_php_embed();
302
+ atexit(shutdown_php_embed);
303
+
304
+ /*
305
+ zend_try {
306
+ zend_alter_ini_entry((char*)"display_errors", sizeof("display_errors")
307
+ , (char*)"0", sizeof("0")-1, PHP_INI_SYSTEM, PHP_INI_STAGE_RUNTIME);
308
+ zend_alter_ini_entry((char*)"log_errors", sizeof("log_errors")
309
+ , (char*)"1", sizeof("1")-1, PHP_INI_SYSTEM, PHP_INI_STAGE_RUNTIME);
310
+ } zend_catch {
311
+ } zend_end_try();
312
+ */
218
313
  }
219
314
 
220
315
 
@@ -0,0 +1,156 @@
1
+ #include <ruby.h>
2
+ #include <php.h>
3
+ #include <php_embed_value.h>
4
+
5
+ static void php_value_mark(php_value* pv) {
6
+ if (pv) {
7
+ rb_gc_mark(pv->value);
8
+ }
9
+ }
10
+
11
+ static void php_value_free(php_value* pv) {
12
+ if (pv) {
13
+ xfree(pv);
14
+ }
15
+ }
16
+
17
+ static VALUE php_value_alloc(VALUE klass) {
18
+ php_value * pv;
19
+ return Data_Make_Struct(klass, php_value, php_value_mark, php_value_free, pv);
20
+ }
21
+
22
+ static int hash_to_php_string_array(VALUE key, VALUE value, VALUE ary) {
23
+ VALUE k,v,r;
24
+ int key_type;
25
+
26
+ if (key == Qundef) {
27
+ return ST_CONTINUE;
28
+ }
29
+
30
+ key_type = TYPE(key);
31
+ if (T_FIXNUM != key_type && T_BIGNUM != key_type
32
+ && T_STRING != key_type && T_SYMBOL != key_type) {
33
+ rb_raise(rb_eRuntimeError, "invalid key (%d)", key_type);
34
+ }
35
+
36
+ k = convert_value_into_php_string(key);
37
+ r = rb_str_new_cstr(RSTRING_PTR(k));
38
+ rb_str_cat2(r, "=>");
39
+ v = convert_value_into_php_string(value);
40
+ rb_str_cat2(r, RSTRING_PTR(v));
41
+
42
+ rb_ary_push(ary, r);
43
+ return ST_CONTINUE;
44
+ }
45
+
46
+ VALUE convert_value_into_php_string(VALUE v) {
47
+ switch (TYPE(v)) {
48
+ case T_FALSE:
49
+ return rb_str_new_cstr("false");
50
+ case T_TRUE:
51
+ return rb_str_new_cstr("true");
52
+ case T_UNDEF:
53
+ case T_NIL:
54
+ return rb_str_new_cstr("null");
55
+ case T_FIXNUM:
56
+ return rb_fix2str(v, 10);
57
+ case T_BIGNUM:
58
+ return rb_big2str(v, 10);
59
+ case T_FLOAT:
60
+ return rb_funcall(v, rb_intern("to_s"), 0);
61
+ case T_ARRAY:
62
+ {
63
+ int i;
64
+ VALUE ret = rb_str_new_cstr("array(");
65
+ for(i=0;i<RARRAY_LEN(v);++i) {
66
+ VALUE p = convert_value_into_php_string(RARRAY_PTR(v)[i]);
67
+ if (T_STRING == TYPE(p)) {
68
+ rb_str_cat2(ret, StringValuePtr(p));
69
+ }
70
+ if (i != RARRAY_LEN(v)-1) {
71
+ rb_str_cat2(ret, ",");
72
+ }
73
+ }
74
+ rb_str_cat2(ret, ")");
75
+ return ret;
76
+ }
77
+ case T_HASH:
78
+ {
79
+ VALUE ret = rb_str_new_cstr("array(");
80
+ VALUE ary = rb_ary_new();
81
+
82
+ rb_hash_foreach(v, hash_to_php_string_array, ary);
83
+
84
+ {
85
+ int i;
86
+ int len = RARRAY_LEN(ary);
87
+
88
+ VALUE* p = RARRAY_PTR(ary);
89
+ for(i=0; i<len; ++i) {
90
+ rb_str_cat2(ret, StringValuePtr(p[i]));
91
+ if (i != len-1) {
92
+ rb_str_cat2(ret, ",");
93
+ }
94
+ }
95
+ }
96
+ rb_str_cat2(ret, ")");
97
+ return ret;
98
+ }
99
+ case T_SYMBOL:
100
+ {
101
+ VALUE symbol_str = rb_sym_to_s(v);
102
+ VALUE ret = rb_str_new_cstr("'");
103
+ rb_str_cat2(ret, StringValuePtr(symbol_str));
104
+ rb_str_cat2(ret, "'");
105
+ return ret;
106
+ }
107
+ case T_STRING:
108
+ {
109
+ VALUE ret = rb_str_new_cstr("'");
110
+ rb_str_cat2(ret, StringValuePtr(v));
111
+ rb_str_cat2(ret, "'");
112
+ return ret;
113
+ }
114
+ default:
115
+ rb_raise(rb_eRuntimeError, "no implemented");
116
+ }
117
+ }
118
+
119
+
120
+ VALUE php_value_initialize(VALUE self, VALUE value) {
121
+ php_value* pv;
122
+ Data_Get_Struct(self, php_value, pv);
123
+
124
+ pv->value = value;
125
+ return Qnil;
126
+ }
127
+
128
+ VALUE php_value_to_string(VALUE self) {
129
+ VALUE ret;
130
+ php_value* pv;
131
+ Data_Get_Struct(self, php_value, pv);
132
+
133
+ return convert_value_into_php_string(pv->value);
134
+ }
135
+
136
+ VALUE php_value_parse_php_string(VALUE self, VALUE php_string) {
137
+ return Qnil;
138
+ }
139
+
140
+
141
+ extern mPhpEmbed;
142
+ VALUE cPhpEmbedValue;
143
+ void init_php_value() {
144
+ #if 0
145
+ mPhpEmbed = rb_define_module("PhpEmbed");
146
+ #endif
147
+
148
+ cPhpEmbedValue = rb_define_class_under(mPhpEmbed, "Value", rb_cObject);
149
+ rb_define_alloc_func(cPhpEmbedValue, php_value_alloc);
150
+ rb_define_method(cPhpEmbedValue, "initialize", php_value_initialize, 1);
151
+ rb_define_method(cPhpEmbedValue, "to_s", php_value_to_string, 0);
152
+
153
+ rb_define_singleton_method(cPhpEmbedValue, "parse", php_value_parse_php_string, 1);
154
+
155
+
156
+ }
@@ -0,0 +1,13 @@
1
+ #ifndef PHP_EMBED_VALUE
2
+ #define PHP_EMBED_VALUE
3
+
4
+ void init_php_value();
5
+
6
+ VALUE convert_value_into_php_string(VALUE v);
7
+
8
+ typedef struct {
9
+ VALUE value;
10
+ } php_value;
11
+
12
+ #endif
13
+
@@ -1,3 +1,3 @@
1
1
  module PhpEmbed
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
data/spec/php_spec.rb CHANGED
@@ -1,18 +1,9 @@
1
1
  # encoding: UTF-8
2
2
  require 'php_embed'
3
3
 
4
- describe 'PhpEmbed' do
4
+ describe PhpEmbed do
5
5
 
6
6
  describe 'eval' do
7
- it 'return any types' do
8
- PhpEmbed.eval('true').should be_true
9
- PhpEmbed.eval('false').should be_false;
10
- PhpEmbed.eval('null').should be_nil
11
- PhpEmbed.eval('1').should == 1
12
- PhpEmbed.eval('array()').should == []
13
- PhpEmbed.eval('array(1)').should == [1]
14
- end
15
-
16
7
  it 'raise error with invalid PhpEmbed code' do
17
8
  proc {
18
9
  PhpEmbed.eval("i n v a l i d")
@@ -20,11 +11,25 @@ describe 'PhpEmbed' do
20
11
  end
21
12
  end
22
13
 
23
- describe 'call' do
24
- it 'return phpversion' do
25
- PhpEmbed.call("phpversion").should == "5.4.5"
26
- end
14
+ describe 'eval and call' do
15
+ it '1' do
16
+ PhpEmbed.eval('function hoge(){ return 1; }');
17
+ PhpEmbed.call('hoge').should == 1;
18
+ end
19
+ it 'any value' do
20
+ PhpEmbed.eval('function hoge2($arg){ return $arg; }');
21
+ PhpEmbed.call('hoge2', 1).should == 1;
22
+ PhpEmbed.call('hoge2', 'a').should == 'a';
23
+ PhpEmbed.call('hoge2', []).should == [];
24
+ PhpEmbed.call('hoge2', [1]).should == [1];
25
+ PhpEmbed.call('hoge2', {0=>1,1=>2}).should == [1,2];
26
+ PhpEmbed.call('hoge2', {10=>2}).should == {10=>2};
27
+ PhpEmbed.call('hoge2', {'a'=>1}).should == {'a'=>1};
28
+ end
29
+ end
27
30
 
31
+
32
+ describe 'call' do
28
33
  it 'bin2hex return hex string' do
29
34
  PhpEmbed.call("bin2hex", "+").should == "2b"
30
35
  end
@@ -44,7 +49,7 @@ describe 'PhpEmbed' do
44
49
  end
45
50
 
46
51
  it 'call with array' do
47
- PhpEmbed.call("array_diff", [1,2,3,4,5], [3,4]).should == [1,2,5]
52
+ PhpEmbed.call("array_diff", [1,2,3,4,5], [3,4]).should == {0=>1,1=>2,4=>5}
48
53
  end
49
54
 
50
55
  it 'raise error with invalid PhpEmbed code' do
@@ -61,7 +66,7 @@ describe 'PhpEmbed' do
61
66
  capture = output
62
67
  })
63
68
 
64
- PhpEmbed.eval('print("hoge")')
69
+ PhpEmbed.eval('print("hoge");')
65
70
  capture.should == 'hoge'
66
71
  end
67
72
  end
@@ -73,13 +78,8 @@ describe 'PhpEmbed' do
73
78
  capture << error
74
79
  })
75
80
 
76
- PhpEmbed.eval('trigger_error("hoge")')
77
- capture.should == [
78
- "PHP Notice: hoge in on line 1",
79
- "PHP Stack trace:",
80
- "PHP 1. {main}() :0",
81
- "PHP 2. trigger_error() :1"
82
- ]
81
+ PhpEmbed.eval('trigger_error("hoge");')
82
+ capture.join('').should match('PHP Notice:')
83
83
  end
84
84
  end
85
85
 
@@ -0,0 +1,29 @@
1
+ describe PhpEmbed::Value do
2
+ it 'convert nil' do
3
+ PhpEmbed::Value.new(nil).to_s.should == 'null';
4
+ end
5
+ it 'convert boolean' do
6
+ PhpEmbed::Value.new(false).to_s.should == 'false';
7
+ PhpEmbed::Value.new(true).to_s.should == 'true';
8
+ end
9
+
10
+ it 'convert scalar' do
11
+ PhpEmbed::Value.new(1).to_s.should == '1';
12
+ PhpEmbed::Value.new("a").to_s.should == "'a'";
13
+ PhpEmbed::Value.new(:a).to_s.should == "'a'";
14
+ end
15
+
16
+ it 'convert array' do
17
+ PhpEmbed::Value.new([]).to_s.should == 'array()';
18
+ PhpEmbed::Value.new([1,2,3]).to_s.should == 'array(1,2,3)';
19
+ PhpEmbed::Value.new(['a', 'b']).to_s.should == "array('a','b')";
20
+ end
21
+
22
+ it 'convert hash' do
23
+ PhpEmbed::Value.new({}).to_s.should == 'array()';
24
+ PhpEmbed::Value.new({1=>'a'}).to_s.should == "array(1=>'a')";
25
+ PhpEmbed::Value.new({'a'=>1}).to_s.should == "array('a'=>1)";
26
+ PhpEmbed::Value.new({:a=>1}).to_s.should == "array('a'=>1)";
27
+ end
28
+ end
29
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: php_embed
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-01 00:00:00.000000000 Z
12
+ date: 2012-09-16 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: execute PHP code in Ruby code
15
15
  email:
@@ -26,10 +26,13 @@ files:
26
26
  - Rakefile
27
27
  - ext/php_embed/extconf.rb
28
28
  - ext/php_embed/php.c
29
+ - ext/php_embed/php_embed_value.c
30
+ - ext/php_embed/php_embed_value.h
29
31
  - lib/php_embed.rb
30
32
  - lib/php_embed/version.rb
31
33
  - php_embed.gemspec
32
34
  - spec/php_spec.rb
35
+ - spec/php_value_spec.rb
33
36
  homepage: https://github.com/do-aki/php_embed
34
37
  licenses: []
35
38
  post_install_message:
@@ -56,3 +59,4 @@ specification_version: 3
56
59
  summary: execute PHP code in Ruby code
57
60
  test_files:
58
61
  - spec/php_spec.rb
62
+ - spec/php_value_spec.rb