php_process 0.0.6 → 0.0.7

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.
data/Gemfile CHANGED
@@ -2,8 +2,9 @@ source "http://rubygems.org"
2
2
  # Add dependencies required to use your gem here.
3
3
  # Example:
4
4
  # gem "activesupport", ">= 2.3.5"
5
- gem "knjrbfw", ">= 0.0.31"
6
5
  gem "php-serialize4ruby"
6
+ gem "wref"
7
+ gem "tsafe"
7
8
 
8
9
  # Add dependencies to develop your gem here.
9
10
  # Include everything needed to run rake, tests, features, etc.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.6
1
+ 0.0.7
@@ -23,7 +23,7 @@ objPHPExcel.getProperties.setDescription("Test document for Office 2007 XLSX, ge
23
23
 
24
24
  #Add some data
25
25
  print "#{Time.now} Add some data\n"
26
- objPHPExcel.setActiveSheetIndex(0);
26
+ objPHPExcel.setActiveSheetIndex(0)
27
27
  objPHPExcel.getActiveSheet.SetCellValue('A1', 'Hello')
28
28
  objPHPExcel.getActiveSheet.SetCellValue('B2', 'world!')
29
29
  objPHPExcel.getActiveSheet.SetCellValue('C1', 'Hello')
data/lib/php_process.rb CHANGED
@@ -1,7 +1,7 @@
1
- require "knjrbfw"
2
- require "knj/wref"
3
- require "base64"
1
+ require "wref"
2
+ require "tsafe"
4
3
  require "php-serialize4ruby"
4
+ require "base64"
5
5
  require "open3"
6
6
 
7
7
  #This class starts a PHP-process and proxies various calls to it. It also spawns proxy-objects, which can you can call like they were normal Ruby-objects.
@@ -32,10 +32,14 @@ class Php_process
32
32
  @args = args
33
33
  @debug = @args[:debug]
34
34
  @send_count = 0
35
- @responses = Knj::Threadsafe::Synced_hash.new
36
- @object_ids = Knj::Threadsafe::Synced_hash.new
37
- @object_unset_ids = Knj::Threadsafe::Synced_array.new
38
- @objects = Knj::Wref_map.new
35
+
36
+ @responses = Tsafe::MonHash.new
37
+
38
+ @object_ids = Tsafe::MonHash.new
39
+ @object_unset_ids = Tsafe::MonArray.new
40
+ @objects = Wref_map.new
41
+
42
+ @constant_val_cache = Tsafe::MonHash.new
39
43
 
40
44
  #Used for 'create_func'.
41
45
  @callbacks = {}
@@ -234,7 +238,13 @@ class Php_process
234
238
 
235
239
  #Returns the value of a constant on the PHP-side.
236
240
  def constant_val(name)
237
- return self.send(:type => :constant_val, :name => name)
241
+ const_name = name.to_s
242
+
243
+ if !@constant_val_cache.key?(const_name)
244
+ @constant_val_cache[const_name] = self.send(:type => :constant_val, :name => name)
245
+ end
246
+
247
+ return @constant_val_cache[const_name]
238
248
  end
239
249
 
240
250
  #Returns various informations about boths sides memory in a hash.
data/lib/php_script.php CHANGED
@@ -1,7 +1,9 @@
1
1
  #!/usr/bin/env php5
2
2
  <?php
3
3
 
4
+ //Controls the PHP-process on the PHP-side.
4
5
  class php_process{
6
+ //Opens stdin and stdout for processing. Sets various helper-variables.
5
7
  function __construct(){
6
8
  $this->sock_stdin = fopen("php://stdin", "r");
7
9
  $this->sock_stdout = fopen("php://stdout", "w");
@@ -10,11 +12,13 @@ class php_process{
10
12
  $this->objects_count = 0;
11
13
  $this->created_functions = array();
12
14
  $this->proxy_to_func = array("call_created_func", "constant_val", "create_func", "func", "get_var", "memory_info", "object_cache_info", "object_call", "require_once_path", "set_var", "static_method_call", "unset_ids");
15
+ $this->func_specials = array("constant", "define", "die", "exit", "require", "require_once", "include", "include_once");
13
16
  $this->send_count = 0;
14
17
 
15
18
  print "php_script_ready:" . getmypid() . "\n";
16
19
  }
17
20
 
21
+ //Starts listening in stdin for new instructions. Calls 'handle_line' for every line gotten.
18
22
  function start_listening(){
19
23
  while(true){
20
24
  $line = fgets($this->sock_stdin, 1048576);
@@ -22,6 +26,7 @@ class php_process{
22
26
  }
23
27
  }
24
28
 
29
+ //Writes the given data to stdout. Serializes and encodes it as well and increases the 'send_count'-variable.
25
30
  function send($data){
26
31
  $id = $this->send_count;
27
32
  $this->send_count++;
@@ -33,6 +38,7 @@ class php_process{
33
38
  //return $this->read_answer($id);
34
39
  }
35
40
 
41
+ //Handles the given instruction. It parses it and then calls the relevant method.
36
42
  function handle_line($line){
37
43
  $data = explode(":", $line);
38
44
  $type = $data[0];
@@ -62,6 +68,7 @@ class php_process{
62
68
  }
63
69
  }
64
70
 
71
+ //Parses objects into special arrays, which again will be turned into proxy-objects on the Ruby-side. Recursivly scans arrays to do the same.
65
72
  function parse_data($data){
66
73
  if (is_array($data)){
67
74
  foreach($data as $key => $val){
@@ -95,6 +102,7 @@ class php_process{
95
102
  }
96
103
  }
97
104
 
105
+ //Recursivly read the given data from the Ruby-side. Changing special arrays into the objects they refer to.
98
106
  function read_parsed_data($data){
99
107
  if (is_array($data) and array_key_exists("type", $data) and $data["type"] == "proxyobj" and array_key_exists("id", $data)){
100
108
  $object = $this->objects[$data["id"]]["obj"];
@@ -117,12 +125,14 @@ class php_process{
117
125
  }
118
126
  }
119
127
 
128
+ //Answers a request ID with the given data. Writes it to stdout.
120
129
  function answer($id, $data){
121
130
  if (!fwrite($this->sock_stdout, "answer:" . $id . ":" . base64_encode(serialize($this->parse_data($data))) . "\n")){
122
131
  throw new exception("Could not write to socket.");
123
132
  }
124
133
  }
125
134
 
135
+ //Ruby wants spawn an object. Cache it and return (Ruby will tell us when to unset it automatically).
126
136
  function new_object($id, $args){
127
137
  $class = $args["class"];
128
138
  $new_args = $this->read_parsed_data($args["args"]);
@@ -133,6 +143,7 @@ class php_process{
133
143
  $this->answer($id, $object);
134
144
  }
135
145
 
146
+ //Ruby wants to set an instance variable on an object. Do that and answer with 'true'.
136
147
  function set_var($id, $args){
137
148
  $object = $this->objects[$args["id"]]["obj"];
138
149
  if (!$object){
@@ -143,6 +154,7 @@ class php_process{
143
154
  $this->answer($id, true);
144
155
  }
145
156
 
157
+ //Ruby wants to read an instance variable on an object. Return the variable's value.
146
158
  function get_var($id, $args){
147
159
  $object = $this->objects[$args["id"]]["obj"];
148
160
  if (!$object){
@@ -152,6 +164,7 @@ class php_process{
152
164
  $this->answer($id, $object->$args["name"]);
153
165
  }
154
166
 
167
+ //Ruby wants to call a method on an object. Do that and return the result.
155
168
  function object_call($id, $args){
156
169
  if (!array_key_exists($args["id"], $this->objects)){
157
170
  throw new exception("No object by that ID: " . $args["id"]);
@@ -173,12 +186,12 @@ class php_process{
173
186
  $this->answer($id, $res);
174
187
  }
175
188
 
189
+ //Ruby wants to call a function. Do that and return the result.
176
190
  function func($id, $args){
177
191
  //These functions cant be called normally. Hack them with eval instead.
178
- $specials = array("die", "exit", "require", "require_once", "include", "include_once");
179
192
  $newargs = $this->read_parsed_data($args["args"]);
180
193
 
181
- if (in_array($args["func_name"], $specials)){
194
+ if (in_array($args["func_name"], $this->func_specials)){
182
195
  $eval_str = $args["func_name"] . "(";
183
196
  $count = 0;
184
197
  foreach($newargs as $key => $val){
@@ -203,6 +216,7 @@ class php_process{
203
216
  $this->answer($id, $res);
204
217
  }
205
218
 
219
+ //Ruby has given us various object-IDs to unset. Unset them from cache and return 'true'.
206
220
  function unset_ids($id, $args){
207
221
  foreach($args["ids"] as $obj_id){
208
222
  if (!array_key_exists($obj_id, $this->objects)){
@@ -222,6 +236,7 @@ class php_process{
222
236
  $this->answer($id, true);
223
237
  }
224
238
 
239
+ //Ruby wants information about the object-cache on the PHP-side. Return that in an array.
225
240
  function object_cache_info($id, $args){
226
241
  $types = array();
227
242
  foreach($this->objects as $key => $val){
@@ -238,6 +253,7 @@ class php_process{
238
253
  ));
239
254
  }
240
255
 
256
+ //Ruby wants to call a static method. Answers with the result.
241
257
  function static_method_call($id, $args){
242
258
  $call_arr = array($args["class_name"], $args["method_name"]);
243
259
 
@@ -255,6 +271,7 @@ class php_process{
255
271
  $this->answer($id, $res);
256
272
  }
257
273
 
274
+ //Creates a function which can be used for callbacks on the Ruby-side.
258
275
  function create_func($id, $args){
259
276
  $cb_id = $args["callback_id"];
260
277
  $func = create_function("", "global \$php_process; \$php_process->call_back_created_func(" . $cb_id . ", func_get_args());");
@@ -266,6 +283,7 @@ class php_process{
266
283
  $this->answer($id, true);
267
284
  }
268
285
 
286
+ //This function is called, when a create-function is called. It then callbacks to Ruby, where a 'Proc' will be executed.
269
287
  function call_back_created_func($func_id, $args){
270
288
  $this->send(array(
271
289
  "type" => "call_back_created_func",
@@ -274,6 +292,7 @@ class php_process{
274
292
  ));
275
293
  }
276
294
 
295
+ //Ruby wants to call a created function. Pretty much just executes that function. This is useually done for debugging callbacks.
277
296
  function call_created_func($id, $args){
278
297
  $func = $this->created_functions[$args["id"]]["func"];
279
298
  if (!$func){
@@ -297,10 +316,12 @@ class php_process{
297
316
  $this->answer($id, $res);
298
317
  }
299
318
 
319
+ //Ruby wants to read a constant. This is not done by 'func', because of keeping caching posibility open and not wanting to eval.
300
320
  function constant_val($id, $args){
301
321
  $this->answer($id, constant($args["name"]));
302
322
  }
303
323
 
324
+ //Returns various information about the object-cache.
304
325
  function memory_info($id, $args){
305
326
  $this->answer($id, array(
306
327
  "objects" => count($this->objects),
data/php_process.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{php_process}
8
- s.version = "0.0.6"
8
+ s.version = "0.0.7"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Kasper Johansen"]
12
- s.date = %q{2012-05-08}
12
+ s.date = %q{2012-05-22}
13
13
  s.description = %q{Spawns a PHP process and proxies calls to it, making it possible to proxy objects and more.}
14
14
  s.email = %q{k@spernj.org}
15
15
  s.extra_rdoc_files = [
@@ -41,16 +41,18 @@ Gem::Specification.new do |s|
41
41
  s.specification_version = 3
42
42
 
43
43
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
44
- s.add_runtime_dependency(%q<knjrbfw>, [">= 0.0.31"])
45
44
  s.add_runtime_dependency(%q<php-serialize4ruby>, [">= 0"])
45
+ s.add_runtime_dependency(%q<wref>, [">= 0"])
46
+ s.add_runtime_dependency(%q<tsafe>, [">= 0"])
46
47
  s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
47
48
  s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
48
49
  s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
49
50
  s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
50
51
  s.add_development_dependency(%q<rcov>, [">= 0"])
51
52
  else
52
- s.add_dependency(%q<knjrbfw>, [">= 0.0.31"])
53
53
  s.add_dependency(%q<php-serialize4ruby>, [">= 0"])
54
+ s.add_dependency(%q<wref>, [">= 0"])
55
+ s.add_dependency(%q<tsafe>, [">= 0"])
54
56
  s.add_dependency(%q<rspec>, ["~> 2.8.0"])
55
57
  s.add_dependency(%q<rdoc>, ["~> 3.12"])
56
58
  s.add_dependency(%q<bundler>, [">= 1.0.0"])
@@ -58,8 +60,9 @@ Gem::Specification.new do |s|
58
60
  s.add_dependency(%q<rcov>, [">= 0"])
59
61
  end
60
62
  else
61
- s.add_dependency(%q<knjrbfw>, [">= 0.0.31"])
62
63
  s.add_dependency(%q<php-serialize4ruby>, [">= 0"])
64
+ s.add_dependency(%q<wref>, [">= 0"])
65
+ s.add_dependency(%q<tsafe>, [">= 0"])
63
66
  s.add_dependency(%q<rspec>, ["~> 2.8.0"])
64
67
  s.add_dependency(%q<rdoc>, ["~> 3.12"])
65
68
  s.add_dependency(%q<bundler>, [">= 1.0.0"])
@@ -11,6 +11,18 @@ describe "PhpProcess" do
11
11
  $php = Php_process.new(:debug => false, :debug_stderr => true)
12
12
 
13
13
 
14
+ #It should be able to handle constants very fast by using cache.
15
+ $php.func("define", "TEST_CONSTANT", 5)
16
+ raise "Expected 'TEST_CONSTANT'-constant to exist but it didnt." if !$php.func("defined", "TEST_CONSTANT")
17
+
18
+ Timeout.timeout(1) do
19
+ 0.upto(10000) do
20
+ const = $php.constant_val("TEST_CONSTANT")
21
+ raise "Expected const to be 5 but it wasnt: #{const}." if const != 5
22
+ end
23
+ end
24
+
25
+
14
26
  #Test function calls without arguments.
15
27
  pid = $php.func("getmypid")
16
28
  raise "Invalid PID: #{pid}" if pid.to_i <= 0
@@ -73,8 +85,7 @@ describe "PhpProcess" do
73
85
  tw.close
74
86
  tw = nil
75
87
 
76
-
77
-
88
+
78
89
  #Test PHPExcel.
79
90
  $php.func("require_once", "PHPExcel.php")
80
91
  tw = $php.new("knj_table_writer", {
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: php_process
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.6
5
+ version: 0.0.7
6
6
  platform: ruby
7
7
  authors:
8
8
  - Kasper Johansen
@@ -10,22 +10,22 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-05-08 00:00:00 +02:00
13
+ date: 2012-05-22 00:00:00 +02:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
- name: knjrbfw
17
+ name: php-serialize4ruby
18
18
  requirement: &id001 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: 0.0.31
23
+ version: "0"
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: *id001
27
27
  - !ruby/object:Gem::Dependency
28
- name: php-serialize4ruby
28
+ name: wref
29
29
  requirement: &id002 !ruby/object:Gem::Requirement
30
30
  none: false
31
31
  requirements:
@@ -36,8 +36,19 @@ dependencies:
36
36
  prerelease: false
37
37
  version_requirements: *id002
38
38
  - !ruby/object:Gem::Dependency
39
- name: rspec
39
+ name: tsafe
40
40
  requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ type: :runtime
47
+ prerelease: false
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: rspec
51
+ requirement: &id004 !ruby/object:Gem::Requirement
41
52
  none: false
42
53
  requirements:
43
54
  - - ~>
@@ -45,10 +56,10 @@ dependencies:
45
56
  version: 2.8.0
46
57
  type: :development
47
58
  prerelease: false
48
- version_requirements: *id003
59
+ version_requirements: *id004
49
60
  - !ruby/object:Gem::Dependency
50
61
  name: rdoc
51
- requirement: &id004 !ruby/object:Gem::Requirement
62
+ requirement: &id005 !ruby/object:Gem::Requirement
52
63
  none: false
53
64
  requirements:
54
65
  - - ~>
@@ -56,10 +67,10 @@ dependencies:
56
67
  version: "3.12"
57
68
  type: :development
58
69
  prerelease: false
59
- version_requirements: *id004
70
+ version_requirements: *id005
60
71
  - !ruby/object:Gem::Dependency
61
72
  name: bundler
62
- requirement: &id005 !ruby/object:Gem::Requirement
73
+ requirement: &id006 !ruby/object:Gem::Requirement
63
74
  none: false
64
75
  requirements:
65
76
  - - ">="
@@ -67,10 +78,10 @@ dependencies:
67
78
  version: 1.0.0
68
79
  type: :development
69
80
  prerelease: false
70
- version_requirements: *id005
81
+ version_requirements: *id006
71
82
  - !ruby/object:Gem::Dependency
72
83
  name: jeweler
73
- requirement: &id006 !ruby/object:Gem::Requirement
84
+ requirement: &id007 !ruby/object:Gem::Requirement
74
85
  none: false
75
86
  requirements:
76
87
  - - ~>
@@ -78,10 +89,10 @@ dependencies:
78
89
  version: 1.8.3
79
90
  type: :development
80
91
  prerelease: false
81
- version_requirements: *id006
92
+ version_requirements: *id007
82
93
  - !ruby/object:Gem::Dependency
83
94
  name: rcov
84
- requirement: &id007 !ruby/object:Gem::Requirement
95
+ requirement: &id008 !ruby/object:Gem::Requirement
85
96
  none: false
86
97
  requirements:
87
98
  - - ">="
@@ -89,7 +100,7 @@ dependencies:
89
100
  version: "0"
90
101
  type: :development
91
102
  prerelease: false
92
- version_requirements: *id007
103
+ version_requirements: *id008
93
104
  description: Spawns a PHP process and proxies calls to it, making it possible to proxy objects and more.
94
105
  email: k@spernj.org
95
106
  executables: []
@@ -127,7 +138,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
127
138
  requirements:
128
139
  - - ">="
129
140
  - !ruby/object:Gem::Version
130
- hash: -4239415254216203709
141
+ hash: 537427075948440521
131
142
  segments:
132
143
  - 0
133
144
  version: "0"