php_process 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
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"