php_vm 1.3.10 → 1.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -73,6 +73,13 @@ static void php_vm_exception_hook(zval *ex TSRMLS_DC)
73
73
  EG(exception) = NULL;
74
74
  }
75
75
 
76
+ static void php_vm_reset_status(TSRMLS_D)
77
+ {
78
+ EG(exit_status) = 0;
79
+ EG(exception) = NULL;
80
+ rb_cv_set(rb_mPHPVM, "@@last_error_reporting", Qnil);
81
+ }
82
+
76
83
 
77
84
  // PHP
78
85
 
@@ -81,12 +88,16 @@ VALUE php_eval_string(char *code, int code_len, int use_retval TSRMLS_DC)
81
88
  int syntax_error = 0;
82
89
  zval retval;
83
90
 
91
+ // reset
92
+ php_vm_reset_status(TSRMLS_C);
93
+
84
94
  // eval
85
95
  zend_try {
86
96
  if (zend_eval_stringl(code, code_len, (use_retval ? &retval : NULL), "php_vm" TSRMLS_CC)==FAILURE) {
87
97
  syntax_error = 1;
88
98
  }
89
99
  } zend_end_try();
100
+ EG(active_op_array) = NULL;
90
101
 
91
102
  // syntax error
92
103
  if (syntax_error) {
@@ -363,6 +374,9 @@ int call_php_method(zend_class_entry *ce, zval *obj, zend_function *mptr, int ar
363
374
  {
364
375
  int result = FAILURE;
365
376
 
377
+ // reset
378
+ php_vm_reset_status(TSRMLS_C);
379
+
366
380
  // call info
367
381
  zend_fcall_info fci;
368
382
  zend_fcall_info_cache fcc;
@@ -421,6 +435,7 @@ int call_php_method(zend_class_entry *ce, zval *obj, zend_function *mptr, int ar
421
435
  // release
422
436
  zend_fcall_info_args_clear(&fci, 1);
423
437
  zval_ptr_dtor(&z_args);
438
+ EG(active_op_array) = NULL;
424
439
 
425
440
  // result
426
441
  if (g_exception || rb_cv_get(rb_mPHPVM, "@@last_error_reporting")!=Qnil) {
@@ -834,6 +849,7 @@ VALUE define_global_classes()
834
849
  while (SUCCESS == zend_hash_get_current_data_ex(ht, (void **)&z_classname, &pos)) {
835
850
  char *classname = Z_STRVAL_P(*z_classname);
836
851
  int classname_len = Z_STRLEN_P(*z_classname);
852
+
837
853
  if (0x41<=classname[0] && classname[0]<=0x5a) {
838
854
  // define class as const if class name is uppercase
839
855
  if (!rb_const_defined(rb_mPHPGlobal, rb_intern(classname))) {
@@ -844,6 +860,7 @@ VALUE define_global_classes()
844
860
  // define class as module function if class name is lowercase
845
861
  rb_define_module_function(rb_mPHPGlobal, classname, rb_php_global_class_call, 0);
846
862
  }
863
+
847
864
  zend_hash_move_forward_ex(ht, &pos);
848
865
  }
849
866
  zval_ptr_dtor(&z_val);
@@ -1467,7 +1484,7 @@ void Init_php_vm()
1467
1484
  rb_define_singleton_method(rb_mPHPVM, "get_class", rb_php_vm_get_class, 1);
1468
1485
  rb_define_singleton_method(rb_mPHPVM, "define_global", rb_php_vm_define_global, 0);
1469
1486
 
1470
- rb_define_const(rb_mPHPVM, "VERSION", rb_str_new2("1.3.10"));
1487
+ rb_define_const(rb_mPHPVM, "VERSION", rb_str_new2("1.3.11"));
1471
1488
 
1472
1489
  rb_cv_set(rb_mPHPVM, "@@output_handler", Qnil);
1473
1490
  rb_cv_set(rb_mPHPVM, "@@error_handler", Qnil);
@@ -82,8 +82,15 @@ static VALUE zval_to_value_object(zval *z)
82
82
  const char *name = "";
83
83
  zend_uint name_len = 0;
84
84
  int dup;
85
+
86
+ // get class name
85
87
  dup = zend_get_object_classname(z, &name, &name_len TSRMLS_CC);
88
+ if (dup!=SUCCESS) {
89
+ rb_raise(rb_ePHPError, "did not get class name from zend_class_entry");
90
+ }
91
+
86
92
  VALUE v_name = rb_str_new(name, name_len);
93
+ efree((char*)name);
87
94
 
88
95
  // class
89
96
  VALUE class = rb_php_class_get(rb_cPHPClass, v_name);
@@ -0,0 +1 @@
1
+ <?php
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'test/unit'
4
+
5
+ test_dir = File.dirname(__FILE__)
6
+ exit Test::Unit::AutoRunner.run(true, test_dir)
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/ruby
2
+
3
+ $LOAD_PATH << File.expand_path(__FILE__+"/../../ext/php_vm")
4
+ require "test/unit"
5
+ require "php_vm"
6
+
7
+ class TC_PHPVM < Test::Unit::TestCase
8
+ def setup
9
+ PHPVM.output_handler = Proc.new{|output| }
10
+ PHPVM.error_handler = Proc.new{|error_reporting| }
11
+ end
12
+
13
+ def test_output_handler_accessor
14
+ hooked_output = nil
15
+ pr = Proc.new {|output|
16
+ hooked_output = output
17
+ }
18
+
19
+ # proc object
20
+ PHPVM.output_handler = pr
21
+ assert_equal(pr, PHPVM.output_handler)
22
+
23
+ # hook
24
+ PHPVM.exec("echo 'HelloWorld';")
25
+ assert_equal("HelloWorld", hooked_output)
26
+
27
+ # nil object
28
+ PHPVM.output_handler = nil
29
+ assert_nil(PHPVM.output_handler)
30
+ end
31
+
32
+ def test_error_handler_accessor
33
+ hooked_error_reporting = nil
34
+ pr = Proc.new {|error_reporting|
35
+ hooked_error_reporting = error_reporting
36
+ }
37
+
38
+ # proc object
39
+ PHPVM.error_handler = pr
40
+ assert_equal(pr, PHPVM.error_handler)
41
+
42
+ # hook
43
+ PHPVM.exec("strpos();")
44
+ assert_instance_of(PHPVM::PHPErrorReporting, hooked_error_reporting)
45
+
46
+ # nil object
47
+ PHPVM.error_handler = nil
48
+ assert_nil(PHPVM.error_handler)
49
+ end
50
+
51
+ def test_require
52
+ # exists php file
53
+ filepath = File.expand_path(__FILE__+"/../require.php")
54
+ assert_equal(true, PHPVM.require(filepath))
55
+
56
+ # non exists php file
57
+ assert_raises(PHPVM::PHPErrorReporting) {
58
+ filepath = File.expand_path(__FILE__+"/../non_exists_file.php")
59
+ PHPVM.require(filepath)
60
+ }
61
+ end
62
+
63
+ def test_require_once
64
+ # exists php file
65
+ filepath = File.expand_path(__FILE__+"/../require.php")
66
+ assert_equal(true, PHPVM.require_once(filepath))
67
+
68
+ # non exists php file
69
+ assert_raises(PHPVM::PHPErrorReporting) {
70
+ filepath = File.expand_path(__FILE__+"/../non_exists_file.php")
71
+ PHPVM.require_once(filepath)
72
+ }
73
+ end
74
+
75
+ def test_include
76
+ # exists php file
77
+ filepath = File.expand_path(__FILE__+"/../require.php")
78
+ assert_equal(true, PHPVM.include(filepath))
79
+
80
+ # non exists php file
81
+ filepath = File.expand_path(__FILE__+"/../non_exists_file.php")
82
+ assert_equal(false, PHPVM.include(filepath))
83
+ end
84
+
85
+ def test_include_once
86
+ # exists php file
87
+ filepath = File.expand_path(__FILE__+"/../require.php")
88
+ assert_equal(true, PHPVM.include_once(filepath))
89
+
90
+ # non exists php file
91
+ filepath = File.expand_path(__FILE__+"/../non_exists_file.php")
92
+ assert_equal(false, PHPVM.include_once(filepath))
93
+ end
94
+
95
+ def test_get_class
96
+ # exists php class
97
+ assert_instance_of(PHPVM::PHPClass, PHPVM.get_class("SimpleXMLElement"))
98
+ assert_equal(PHPVM::PHPClass.get("SimpleXMLElement"), PHPVM.get_class("SimpleXMLElement"))
99
+
100
+ # non exists php class
101
+ assert_raises(PHPVM::PHPError) {
102
+ PHPVM.get_class("NonExistsClass")
103
+ }
104
+ end
105
+
106
+ def test_define_global
107
+ assert_equal(true, PHPVM.define_global)
108
+ end
109
+
110
+ def test_version
111
+ assert_match(/^\d+\.\d+\.\d+$/, PHPVM::VERSION)
112
+ end
113
+ end
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/ruby
2
+
3
+ $LOAD_PATH << File.expand_path(__FILE__+"/../../ext/php_vm")
4
+ require "test/unit"
5
+ require "php_vm"
6
+
7
+ class TC_PHPVM_PHPClass < Test::Unit::TestCase
8
+ def setup
9
+ PHPVM.output_handler = Proc.new{|output| }
10
+ PHPVM.error_handler = Proc.new{|error_reporting| }
11
+ end
12
+
13
+ def test_get
14
+ # exists php class
15
+ assert_instance_of(PHPVM::PHPClass, PHPVM::PHPClass.get("SimpleXMLElement"))
16
+
17
+ # non exists php class
18
+ assert_raises(PHPVM::PHPError) {
19
+ PHPVM.get_class("NonExistsClass")
20
+ }
21
+ end
22
+
23
+ def test_new
24
+ # normal object
25
+ phpSimpleXMLElement = PHPVM.get_class("SimpleXMLElement")
26
+ xml = phpSimpleXMLElement.new("<root><item>Hello World!!</item></root>")
27
+ assert_instance_of(PHPVM::PHPObject, xml)
28
+
29
+ # exception object
30
+ phpException = PHPVM.get_class("Exception")
31
+ exc = phpException.new("php error")
32
+ assert_instance_of(PHPVM::PHPExceptionObject, exc)
33
+ end
34
+
35
+ def test_name
36
+ phpSimpleXMLElement = PHPVM.get_class("SimpleXMLElement")
37
+ assert_equal("SimpleXMLElement", phpSimpleXMLElement.name)
38
+ end
39
+ end
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/ruby
2
+
3
+ $LOAD_PATH << File.expand_path(__FILE__+"/../../ext/php_vm")
4
+ require "test/unit"
5
+ require "php_vm"
6
+
7
+ class TC_PHPVM_PHPErrorReporting < Test::Unit::TestCase
8
+ def setup
9
+ PHPVM.output_handler = Proc.new{|output| }
10
+ PHPVM.error_handler = Proc.new{|error_reporting| }
11
+ PHPVM.error_handler = nil
12
+ end
13
+
14
+ def test_raise_exception
15
+ assert_raises(PHPVM::PHPErrorReporting) {
16
+ PHPVM.exec("trigger_error('fatal err', E_USER_ERROR);")
17
+ }
18
+
19
+ assert_raises(PHPVM::PHPErrorReporting) {
20
+ PHPVM::PHPGlobal.trigger_error("fatal err", PHPVM::PHPGlobal::E_USER_ERROR)
21
+ }
22
+ end
23
+ end
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/ruby
2
+
3
+ $LOAD_PATH << File.expand_path(__FILE__+"/../../ext/php_vm")
4
+ require "test/unit"
5
+ require "php_vm"
6
+
7
+ class TC_PHPVM_PHPExceptionObject < Test::Unit::TestCase
8
+ def setup
9
+ PHPVM.output_handler = Proc.new{|output| }
10
+ PHPVM.error_handler = Proc.new{|error_reporting| }
11
+ end
12
+
13
+ def test_raise_exception
14
+ assert_raises(PHPVM::PHPExceptionObject) {
15
+ PHPVM.exec("throw new Exception('error');")
16
+ }
17
+ end
18
+ end
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/ruby
2
+
3
+ $LOAD_PATH << File.expand_path(__FILE__+"/../../ext/php_vm")
4
+ require "test/unit"
5
+ require "php_vm"
6
+
7
+ class TC_PHPVM_PHPGlobal < Test::Unit::TestCase
8
+ def setup
9
+ PHPVM.output_handler = Proc.new{|output| }
10
+ PHPVM.error_handler = Proc.new{|error_reporting| }
11
+ end
12
+
13
+ def test_require
14
+ # exists php file
15
+ filepath = File.expand_path(__FILE__+"/../require.php")
16
+ assert_equal(true, PHPVM::PHPGlobal.require(filepath))
17
+
18
+ # exists ruby file
19
+ # return false if require already imported file.
20
+ filepath = "rubygems"
21
+ assert_equal(false, PHPVM::PHPGlobal.require(filepath))
22
+
23
+ # non exists file
24
+ assert_raises(LoadError) {
25
+ filepath = File.expand_path(__FILE__+"/../non_exists_file.php")
26
+ PHPVM::PHPGlobal.require(filepath)
27
+ }
28
+ end
29
+
30
+ def test_require_once
31
+ # exists php file
32
+ filepath = File.expand_path(__FILE__+"/../require.php")
33
+ assert_equal(true, PHPVM::PHPGlobal.require_once(filepath))
34
+
35
+ # exists ruby file
36
+ # return false if require already imported file.
37
+ filepath = "rubygems"
38
+ assert_equal(false, PHPVM::PHPGlobal.require(filepath))
39
+
40
+ # non exists file
41
+ assert_raises(LoadError) {
42
+ filepath = File.expand_path(__FILE__+"/../non_exists_file.php")
43
+ PHPVM::PHPGlobal.require_once(filepath)
44
+ }
45
+ end
46
+
47
+ def test_echo
48
+ hooked_output = nil
49
+ PHPVM.output_handler = Proc.new{|output|
50
+ hooked_output = output
51
+ }
52
+
53
+ # string
54
+ PHPVM::PHPGlobal.echo("abcdefg")
55
+ assert_equal("abcdefg", hooked_output)
56
+
57
+ # array
58
+ PHPVM::PHPGlobal.echo([])
59
+ assert_equal("Array", hooked_output)
60
+ end
61
+
62
+ def test_print
63
+ hooked_output = nil
64
+ PHPVM.output_handler = Proc.new{|output|
65
+ hooked_output = output
66
+ }
67
+
68
+ # string
69
+ PHPVM::PHPGlobal.print("abcdefg")
70
+ assert_equal("abcdefg", hooked_output)
71
+
72
+ # array
73
+ PHPVM::PHPGlobal.print([])
74
+ assert_equal("Array", hooked_output)
75
+ end
76
+
77
+ def test_array
78
+ assert_equal([], PHPVM::PHPGlobal.array())
79
+ assert_equal([1, 2, 3], PHPVM::PHPGlobal.array(1, 2, 3))
80
+ assert_equal({"aaa"=>"bbb"}, PHPVM::PHPGlobal.array("aaa"=>"bbb"))
81
+ end
82
+
83
+ def test_native_function
84
+ # http_build_query
85
+ assert_equal("aaa=bbb", PHPVM::PHPGlobal.http_build_query({"aaa"=>"bbb"}))
86
+
87
+ # preg_replace
88
+ assert_equal("aBcdef", PHPVM::PHPGlobal.preg_replace('/b/', "B", "abcdef"))
89
+
90
+ # number_format
91
+ assert_equal("123,456,789", PHPVM::PHPGlobal.number_format(123456789))
92
+ end
93
+
94
+ def test_native_class
95
+ # stdClass
96
+ assert_instance_of(PHPVM::PHPClass, PHPVM::PHPGlobal::stdClass)
97
+ assert_equal(PHPVM::PHPClass.get("stdClass"), PHPVM::PHPGlobal::stdClass)
98
+
99
+ # SimpleXMLElement
100
+ assert_instance_of(PHPVM::PHPClass, PHPVM::PHPGlobal::SimpleXMLElement)
101
+ assert_equal(PHPVM::PHPClass.get("SimpleXMLElement"), PHPVM::PHPGlobal::SimpleXMLElement)
102
+
103
+ xml = PHPVM::PHPGlobal::SimpleXMLElement.new("<root><item>Hello World!!</item></root>")
104
+ assert_equal("Hello World!!", xml.item.to_s)
105
+ end
106
+
107
+ def test_native_constant
108
+ # PHP_VERSION
109
+ assert_match(/^\d+\.\d+\.\d+$/, PHPVM::PHPGlobal::PHP_VERSION)
110
+ end
111
+ end
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/ruby
2
+
3
+ $LOAD_PATH << File.expand_path(__FILE__+"/../../ext/php_vm")
4
+ require "test/unit"
5
+ require "php_vm"
6
+
7
+ class TC_PHPVM_PHPObject < Test::Unit::TestCase
8
+ def setup
9
+ PHPVM.output_handler = Proc.new{|output| }
10
+ PHPVM.error_handler = Proc.new{|error_reporting| }
11
+
12
+ # define MagicAccessor
13
+ begin
14
+ PHPVM.get_class("MagicAccessor")
15
+ rescue => e
16
+ PHPVM.exec <<-EOS
17
+ class MagicAccessor
18
+ {
19
+ protected $_data = array();
20
+
21
+ public function __get($name)
22
+ {
23
+ return isset($this->_data[$name]) ? $this->_data[$name] : null;
24
+ }
25
+
26
+ public function __set($name, $val)
27
+ {
28
+ $this->_data[$name] = $val;
29
+ }
30
+ }
31
+ EOS
32
+ end
33
+
34
+ # define MagicCaller
35
+ begin
36
+ PHPVM.get_class("MagicCaller")
37
+ rescue => e
38
+ PHPVM.exec <<-EOS
39
+ class MagicCaller
40
+ {
41
+ public function __call($name, $args)
42
+ {
43
+ return $name." ".implode(", ", $args);
44
+ }
45
+ }
46
+ EOS
47
+ end
48
+ end
49
+
50
+ def test_php_class
51
+ phpSimpleXMLElement = PHPVM.get_class("SimpleXMLElement")
52
+ xml = phpSimpleXMLElement.new("<root><item>Hello World!!</item></root>")
53
+
54
+ assert_equal(phpSimpleXMLElement, xml.php_class)
55
+ end
56
+
57
+ def test_call
58
+ phpException = PHPVM.get_class("Exception")
59
+ exc = phpException.new("exc message", 123)
60
+
61
+ assert_equal("exc message", exc.getMessage)
62
+ assert_equal(123, exc.getCode)
63
+ end
64
+
65
+ def test_magic_access
66
+ # default object handler
67
+ phpMagicAccessor = PHPVM.get_class("MagicAccessor")
68
+ acc = phpMagicAccessor.new
69
+ acc.aaa = "AAA"
70
+
71
+ assert_equal("AAA", acc.aaa)
72
+ assert_nil(acc.bbb)
73
+
74
+ # custom object handler
75
+ phpSimpleXMLElement = PHPVM.get_class("SimpleXMLElement")
76
+ xml = phpSimpleXMLElement.new("<root><item>Hello World!!</item></root>")
77
+
78
+ assert_equal("Hello World!!", xml.item.to_s)
79
+ end
80
+
81
+ def test_magic_call
82
+ phpMagicCaller = PHPVM.get_class("MagicCaller")
83
+ cal = phpMagicCaller.new
84
+
85
+ assert_equal("hello aaa, bbb, ccc", cal.hello("aaa", "bbb", "ccc"))
86
+ end
87
+ end
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/ruby
2
+
3
+ $LOAD_PATH << File.expand_path(__FILE__+"/../../ext/php_vm")
4
+ require "test/unit"
5
+ require "php_vm"
6
+
7
+ class TC_PHPVM_PHPSyntaxError < Test::Unit::TestCase
8
+ def setup
9
+ PHPVM.output_handler = Proc.new{|output| }
10
+ PHPVM.error_handler = Proc.new{|error_reporting| }
11
+ end
12
+
13
+ def test_raise_exception
14
+ assert_raises(PHPVM::PHPSyntaxError) {
15
+ PHPVM.exec("invalid syntax code")
16
+ }
17
+ end
18
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: php_vm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.10
4
+ version: 1.3.11
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: 2013-01-08 00:00:00.000000000 Z
12
+ date: 2013-01-09 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: php_vm is a native bridge between Ruby and PHP.
15
15
  email:
@@ -31,6 +31,15 @@ files:
31
31
  - ext/php_vm/php_vm_z2v.c
32
32
  - ext/php_vm/php_vm_z2v.h
33
33
  - php_vm.gemspec
34
+ - test/require.php
35
+ - test/run_test.rb
36
+ - test/test_php_vm.rb
37
+ - test/test_php_vm_php_class.rb
38
+ - test/test_php_vm_php_error_reporting.rb
39
+ - test/test_php_vm_php_exception_object.rb
40
+ - test/test_php_vm_php_global.rb
41
+ - test/test_php_vm_php_object.rb
42
+ - test/test_php_vm_php_syntax_error.rb
34
43
  homepage: https://github.com/yoshida-eth0/ruby-php_vm
35
44
  licenses: []
36
45
  post_install_message:
@@ -55,4 +64,13 @@ rubygems_version: 1.8.23
55
64
  signing_key:
56
65
  specification_version: 3
57
66
  summary: php_vm is a native bridge between Ruby and PHP.
58
- test_files: []
67
+ test_files:
68
+ - test/require.php
69
+ - test/run_test.rb
70
+ - test/test_php_vm.rb
71
+ - test/test_php_vm_php_class.rb
72
+ - test/test_php_vm_php_error_reporting.rb
73
+ - test/test_php_vm_php_exception_object.rb
74
+ - test/test_php_vm_php_global.rb
75
+ - test/test_php_vm_php_object.rb
76
+ - test/test_php_vm_php_syntax_error.rb