php_process 0.0.1 → 0.0.2
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/VERSION +1 -1
- data/lib/php_process.rb +106 -4
- data/lib/php_script.php +147 -28
- data/php_process.gemspec +69 -0
- data/spec/php_process_spec.rb +50 -5
- metadata +18 -17
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.0.
|
|
1
|
+
0.0.2
|
data/lib/php_process.rb
CHANGED
|
@@ -29,6 +29,11 @@ class Php_process
|
|
|
29
29
|
@object_ids = Knj::Threadsafe::Synced_hash.new
|
|
30
30
|
@object_unset_ids = Knj::Threadsafe::Synced_array.new
|
|
31
31
|
|
|
32
|
+
#Used for 'create_func'.
|
|
33
|
+
@callbacks = {}
|
|
34
|
+
@callbacks_count = 0
|
|
35
|
+
@callbacks_mutex = Mutex.new
|
|
36
|
+
|
|
32
37
|
cmd_str = "/usr/bin/env php5 \"#{File.dirname(__FILE__)}/php_script.php\""
|
|
33
38
|
|
|
34
39
|
if RUBY_ENGINE == "jruby"
|
|
@@ -50,7 +55,7 @@ class Php_process
|
|
|
50
55
|
end
|
|
51
56
|
|
|
52
57
|
@args[:on_err].call(str) if @args[:on_err]
|
|
53
|
-
$stderr.print "Process error: #{str}" if @debug
|
|
58
|
+
$stderr.print "Process error: #{str}" if @debug or @args[:debug_stderr]
|
|
54
59
|
end
|
|
55
60
|
end
|
|
56
61
|
|
|
@@ -119,7 +124,7 @@ class Php_process
|
|
|
119
124
|
# pe = php.new("PHPExcel")
|
|
120
125
|
# pe.getProperties.setCreator("kaspernj")
|
|
121
126
|
def new(classname, *args)
|
|
122
|
-
return self.send(:type => :new, :class => classname, :args => args)["object"]
|
|
127
|
+
return self.send(:type => :new, :class => classname, :args => parse_data(args))["object"]
|
|
123
128
|
end
|
|
124
129
|
|
|
125
130
|
#Call a function in PHP.
|
|
@@ -128,7 +133,37 @@ class Php_process
|
|
|
128
133
|
# pid_of_php_process = php.func("getmypid")
|
|
129
134
|
# php.func("require_once", "PHPExcel.php")
|
|
130
135
|
def func(func_name, *args)
|
|
131
|
-
return self.send(:type => :func, :func_name => func_name, :args => args)["result"]
|
|
136
|
+
return self.send(:type => :func, :func_name => func_name, :args => parse_data(args))["result"]
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
#Sends a call to a static method on a class with given arguments.
|
|
140
|
+
#===Examples
|
|
141
|
+
# php.static("Gtk", "main_quit")
|
|
142
|
+
def static(class_name, method_name, *args)
|
|
143
|
+
return self.send(:type => :static_method_call, :class_name => class_name, :method_name => method_name, :args => parse_data(args))["result"]
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
#Creates a function on the PHP-side. When the function is called, it callbacks to the Ruby-side which then can execute stuff back to PHP.
|
|
147
|
+
#===Examples
|
|
148
|
+
# func = php.create_func do |d|
|
|
149
|
+
# d.php.static("Gtk", "main_quit")
|
|
150
|
+
# end
|
|
151
|
+
#
|
|
152
|
+
# button.connect("clicked", func)
|
|
153
|
+
def create_func(args = {}, &block)
|
|
154
|
+
callback_id = nil
|
|
155
|
+
func = nil
|
|
156
|
+
@callbacks_mutex.synchronize do
|
|
157
|
+
callback_id = @callbacks_count
|
|
158
|
+
func = Php_process::Created_function.new(:php => self, :id => callback_id)
|
|
159
|
+
@callbacks[callback_id] = {:block => block, :func => func, :id => callback_id}
|
|
160
|
+
@callbacks_count += 1
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
raise "No callback-ID?" if !callback_id
|
|
164
|
+
self.send(:type => :create_func, :callback_id => callback_id)
|
|
165
|
+
|
|
166
|
+
return func
|
|
132
167
|
end
|
|
133
168
|
|
|
134
169
|
#This flushes the unset IDs to the PHP-process and frees memory. This is automatically called if 500 IDs are waiting to be flushed. Normally you would not need or have to call this manually.
|
|
@@ -142,6 +177,36 @@ class Php_process
|
|
|
142
177
|
end
|
|
143
178
|
end
|
|
144
179
|
|
|
180
|
+
#Parses argument-data into special hashes that can be used on the PHP-side. It is public because the proxy-objects uses it. Normally you would never use it.
|
|
181
|
+
def parse_data(data)
|
|
182
|
+
if data.is_a?(Php_process::Proxy_obj)
|
|
183
|
+
return {:type => "php_process_proxy", :id => data.args[:id]}
|
|
184
|
+
elsif data.is_a?(Php_process::Created_function)
|
|
185
|
+
return {:type => "php_process_created_function", :id => data.args[:id]}
|
|
186
|
+
elsif data.is_a?(Hash)
|
|
187
|
+
newhash = {}
|
|
188
|
+
data.each do |key, val|
|
|
189
|
+
newhash[key] = parse_data(val)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
return newhash
|
|
193
|
+
elsif data.is_a?(Array)
|
|
194
|
+
newarr = []
|
|
195
|
+
data.each do |val|
|
|
196
|
+
newarr << parse_data(val)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
return newarr
|
|
200
|
+
else
|
|
201
|
+
return data
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
#Returns the value of a constant on the PHP-side.
|
|
206
|
+
def constant_val(name)
|
|
207
|
+
return self.send(:type => :constant_val, :name => name)["result"]
|
|
208
|
+
end
|
|
209
|
+
|
|
145
210
|
private
|
|
146
211
|
|
|
147
212
|
#Generates the command from the given object and sends it to the PHP-process. Then returns the parsed result.
|
|
@@ -217,6 +282,13 @@ class Php_process
|
|
|
217
282
|
|
|
218
283
|
if type == "answer"
|
|
219
284
|
@responses[id] = args
|
|
285
|
+
elsif type == "send"
|
|
286
|
+
if args["type"] == "call_back_created_func"
|
|
287
|
+
Knj::Thread.new do
|
|
288
|
+
func_d = @callbacks[args["func_id"].to_i]
|
|
289
|
+
func_d[:block].call(*args["args"])
|
|
290
|
+
end
|
|
291
|
+
end
|
|
220
292
|
else
|
|
221
293
|
raise "Unknown type: '#{type}'."
|
|
222
294
|
end
|
|
@@ -231,6 +303,9 @@ end
|
|
|
231
303
|
# pe = php.new("PHPExcel")
|
|
232
304
|
# pe.getProperties.setCreator("kaspernj")
|
|
233
305
|
class Php_process::Proxy_obj
|
|
306
|
+
#Contains the various data about the object like ID and class. It is readable because it needs to be converted to special hashes when used as arguments.
|
|
307
|
+
attr_reader :args
|
|
308
|
+
|
|
234
309
|
#Sets required instance-variables and defines the finalizer for unsetting on the PHP-side.
|
|
235
310
|
def initialize(args)
|
|
236
311
|
@args = args
|
|
@@ -268,6 +343,33 @@ class Php_process::Proxy_obj
|
|
|
268
343
|
|
|
269
344
|
#Uses 'method_missing' to proxy all other calls onto the PHP-process and the PHP-object. Then returns the parsed result.
|
|
270
345
|
def method_missing(method_name, *args)
|
|
271
|
-
return @args[:php].send(:type => :object_call, :method => method_name, :args => args, :id => @args[:id])["result"]
|
|
346
|
+
return @args[:php].send(:type => :object_call, :method => method_name, :args => @args[:php].parse_data(args), :id => @args[:id])["result"]
|
|
347
|
+
end
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
#This class handels the ability to create functions on the PHP-side.
|
|
351
|
+
#===Examples
|
|
352
|
+
# $callback_from_php = "test"
|
|
353
|
+
# func = php.create_func do |arg|
|
|
354
|
+
# $callback_from_php = arg
|
|
355
|
+
# end
|
|
356
|
+
#
|
|
357
|
+
# $callback_from_php #=> "test"
|
|
358
|
+
# func.call('test2')
|
|
359
|
+
# $callback_from_php #=> "test2"
|
|
360
|
+
#
|
|
361
|
+
# The function could also be called from PHP, but for debugging purposes it can also be done from Ruby.
|
|
362
|
+
class Php_process::Created_function
|
|
363
|
+
#Various data about the create function will can help identify it on both the Ruby and PHP-side.
|
|
364
|
+
attr_reader :args
|
|
365
|
+
|
|
366
|
+
#Sets the data. This is done from "Php_process" automatically.
|
|
367
|
+
def initialize(args)
|
|
368
|
+
@args = args
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
#Asks PHP to execute the function on the PHP-side, which will trigger the callback in Ruby afterwards. This method is useually called for debugging purposes.
|
|
372
|
+
def call(*args)
|
|
373
|
+
@args[:php].send(:type => :call_created_func, :id => @args[:id], :args => @args[:php].parse_data(args))
|
|
272
374
|
end
|
|
273
375
|
end
|
data/lib/php_script.php
CHANGED
|
@@ -7,35 +7,54 @@ class php_process{
|
|
|
7
7
|
$this->sock_stdout = fopen("php://stdout", "w");
|
|
8
8
|
$this->objects = array();
|
|
9
9
|
$this->objects_count = 0;
|
|
10
|
-
$
|
|
10
|
+
$this->created_functions = array();
|
|
11
|
+
$this->proxy_to_func = array("call_created_func", "constant_val", "create_func", "func", "get_var", "object_cache_info", "object_call", "require_once_path", "set_var", "static_method_call", "unset_ids");
|
|
12
|
+
$this->send_count = 0;
|
|
11
13
|
|
|
12
14
|
print "php_script_ready:" . getmypid() . "\n";
|
|
13
|
-
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function start_listening(){
|
|
14
18
|
while(true){
|
|
15
19
|
$line = fgets($this->sock_stdin, 1048576);
|
|
16
|
-
$
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
20
|
+
$this->handle_line($line);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function send($data){
|
|
25
|
+
$id = $this->send_count;
|
|
26
|
+
$this->send_count++;
|
|
27
|
+
$data_packed = trim(base64_encode(serialize($data)));
|
|
28
|
+
if (!fwrite($this->sock_stdout, "send:" . $id . ":" . $data_packed . "\n")){
|
|
29
|
+
throw new exception("Could not write to stdout.");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
//return $this->read_answer($id);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function handle_line($line){
|
|
36
|
+
$data = explode(":", $line);
|
|
37
|
+
$type = $data[0];
|
|
38
|
+
$id = intval($data[1]);
|
|
39
|
+
$args = unserialize(base64_decode($data[2]));
|
|
40
|
+
|
|
41
|
+
try{
|
|
42
|
+
if ($type == "send"){
|
|
43
|
+
if ($args["type"] == "eval"){
|
|
44
|
+
$res = eval($args["eval_str"] . ";");
|
|
45
|
+
$this->answer($id, $res);
|
|
46
|
+
}elseif($args["type"] == "new"){
|
|
47
|
+
$this->new_object($id, $args);
|
|
48
|
+
}elseif(in_array($args["type"], $this->proxy_to_func)){
|
|
49
|
+
$this->$args["type"]($id, $args);
|
|
33
50
|
}else{
|
|
34
|
-
throw new exception("
|
|
51
|
+
throw new exception("Unknown send-type: " . $args["type"]);
|
|
35
52
|
}
|
|
36
|
-
}
|
|
37
|
-
|
|
53
|
+
}else{
|
|
54
|
+
throw new exception("Invalid type: " . $type);
|
|
38
55
|
}
|
|
56
|
+
}catch(exception $e){
|
|
57
|
+
$this->answer($id, array("type" => "error", "msg" => $e->getMessage(), "bt" => $e->getTraceAsString()));
|
|
39
58
|
}
|
|
40
59
|
}
|
|
41
60
|
|
|
@@ -60,6 +79,28 @@ class php_process{
|
|
|
60
79
|
}
|
|
61
80
|
}
|
|
62
81
|
|
|
82
|
+
function read_parsed_data($data){
|
|
83
|
+
if (is_array($data) and array_key_exists("type", $data) and $data["type"] == "php_process_proxy" and array_key_exists("id", $data) and $data["id"]){
|
|
84
|
+
$object = $this->objects[$data["id"]];
|
|
85
|
+
if (!$object){
|
|
86
|
+
throw new exception("No object by that ID: " . $data["id"]);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return $object;
|
|
90
|
+
}elseif(is_array($data) and array_key_exists("type", $data) and $data["type"] == "php_process_created_function" and array_key_exists("id", $data) and $data["id"]){
|
|
91
|
+
$func = $this->created_functions[$data["id"]]["func"];
|
|
92
|
+
return $func;
|
|
93
|
+
}elseif(is_array($data)){
|
|
94
|
+
foreach($data as $key => $val){
|
|
95
|
+
$data[$key] = $this->read_parsed_data($val);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return $data;
|
|
99
|
+
}else{
|
|
100
|
+
return $data;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
63
104
|
function answer($id, $data){
|
|
64
105
|
if (!fwrite($this->sock_stdout, "answer:" . $id . ":" . base64_encode(serialize($this->parse_data($data))) . "\n")){
|
|
65
106
|
throw new exception("Could not write to socket.");
|
|
@@ -68,7 +109,7 @@ class php_process{
|
|
|
68
109
|
|
|
69
110
|
function new_object($id, $args){
|
|
70
111
|
$class = $args["class"];
|
|
71
|
-
$new_args = $args["args"];
|
|
112
|
+
$new_args = $this->read_parsed_data($args["args"]);
|
|
72
113
|
|
|
73
114
|
$klass = new ReflectionClass($class);
|
|
74
115
|
$object = $klass->newInstanceArgs($new_args);
|
|
@@ -106,11 +147,18 @@ class php_process{
|
|
|
106
147
|
|
|
107
148
|
function object_call($id, $args){
|
|
108
149
|
$object = $this->objects[$args["id"]];
|
|
150
|
+
$call_arr = array($object, $args["method"]);
|
|
151
|
+
|
|
152
|
+
//Error handeling.
|
|
109
153
|
if (!$object){
|
|
110
154
|
throw new exception("No object by that ID: " . $args["id"]);
|
|
155
|
+
}elseif(!method_exists($object, $args["method"])){
|
|
156
|
+
throw new exception("No such method: " . get_class($object) . "->" . $args["method"] . "()");
|
|
157
|
+
}elseif(!is_callable($call_arr)){
|
|
158
|
+
throw new exception("Not callable: " . get_class($object) . "->" . $args["method"] . "()");
|
|
111
159
|
}
|
|
112
160
|
|
|
113
|
-
$res = call_user_func_array(
|
|
161
|
+
$res = call_user_func_array($call_arr, $this->read_parsed_data($args["args"]));
|
|
114
162
|
$this->answer($id, array(
|
|
115
163
|
"result" => $res
|
|
116
164
|
));
|
|
@@ -118,12 +166,13 @@ class php_process{
|
|
|
118
166
|
|
|
119
167
|
function func($id, $args){
|
|
120
168
|
//These functions cant be called normally. Hack them with eval instead.
|
|
121
|
-
$specials = array("require", "require_once", "include", "include_once");
|
|
169
|
+
$specials = array("die", "exit", "require", "require_once", "include", "include_once");
|
|
170
|
+
$newargs = $this->read_parsed_data($args["args"]);
|
|
122
171
|
|
|
123
172
|
if (in_array($args["func_name"], $specials)){
|
|
124
173
|
$eval_str = $args["func_name"] . "(";
|
|
125
174
|
$count = 0;
|
|
126
|
-
foreach($
|
|
175
|
+
foreach($newargs as $key => $val){
|
|
127
176
|
if (!is_numeric($key)){
|
|
128
177
|
throw new exception("Invalid key: '" . $key . "'.");
|
|
129
178
|
}
|
|
@@ -139,8 +188,9 @@ class php_process{
|
|
|
139
188
|
|
|
140
189
|
$res = eval($eval_str);
|
|
141
190
|
}else{
|
|
142
|
-
$res = call_user_func_array($args["func_name"], $
|
|
191
|
+
$res = call_user_func_array($args["func_name"], $newargs);
|
|
143
192
|
}
|
|
193
|
+
|
|
144
194
|
$this->answer($id, array("result" => $res));
|
|
145
195
|
}
|
|
146
196
|
|
|
@@ -167,6 +217,75 @@ class php_process{
|
|
|
167
217
|
"types" => $types
|
|
168
218
|
));
|
|
169
219
|
}
|
|
220
|
+
|
|
221
|
+
function static_method_call($id, $args){
|
|
222
|
+
$call_arr = array($args["class_name"], $args["method_name"]);
|
|
223
|
+
|
|
224
|
+
if (!class_exists($args["class_name"])){
|
|
225
|
+
throw new exception("Class does not exist: '" . $args["class_name"] . "'.");
|
|
226
|
+
}elseif(!method_exists($args["class_name"], $args["method_name"])){
|
|
227
|
+
throw new exception("Such a static method does not exist: " . $args["class_name"] . "::" . $args["method_name"] . "()");
|
|
228
|
+
}elseif(!is_callable($call_arr)){
|
|
229
|
+
throw new exception("Invalid class-name (" . $args["class_name"] . ") or method-name (" . $args["method_name"] . "). It was not callable.");
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
$newargs = $this->read_parsed_data($args["args"]);
|
|
233
|
+
error_log("Args: " . print_r($newargs, true));
|
|
234
|
+
$res = call_user_func_array($call_arr, $newargs);
|
|
235
|
+
|
|
236
|
+
$this->answer($id, array(
|
|
237
|
+
"result" => $res
|
|
238
|
+
));
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function create_func($id, $args){
|
|
242
|
+
$cb_id = $args["callback_id"];
|
|
243
|
+
$func = create_function("", "global \$php_process; \$php_process->call_back_created_func(" . $cb_id . ", func_get_args());");
|
|
244
|
+
if (!$func){
|
|
245
|
+
throw new exception("Could not create function.");
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
$this->created_functions[$cb_id] = array("func" => $func);
|
|
249
|
+
$this->answer($id, true);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function call_back_created_func($func_id, $args){
|
|
253
|
+
$this->send(array(
|
|
254
|
+
"type" => "call_back_created_func",
|
|
255
|
+
"func_id" => $func_id,
|
|
256
|
+
"args" => $args
|
|
257
|
+
));
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function call_created_func($id, $args){
|
|
261
|
+
$func = $this->created_functions[$args["id"]]["func"];
|
|
262
|
+
if (!$func){
|
|
263
|
+
throw new exception("No created function by that ID: '" . $args["id"] . "'.\n\n" . print_r($args, true) . "\n\n" . print_r($this->created_functions, true));
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
$eval_str = "\$func(";
|
|
267
|
+
$count = 0;
|
|
268
|
+
|
|
269
|
+
foreach($args["args"] as $key => $val){
|
|
270
|
+
if ($count > 0){
|
|
271
|
+
$eval_str .= ", ";
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
$eval_str .= "\$args['args'][" . $count . "]";
|
|
275
|
+
$count++;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
$eval_str .= ");";
|
|
279
|
+
$res = eval($eval_str);
|
|
280
|
+
$this->answer($id, array("result" => $res));
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function constant_val($id, $args){
|
|
284
|
+
$this->answer($id, array(
|
|
285
|
+
"result" => constant($args["name"])
|
|
286
|
+
));
|
|
287
|
+
}
|
|
170
288
|
}
|
|
171
289
|
|
|
172
|
-
$php_process = new php_process();
|
|
290
|
+
$php_process = new php_process();
|
|
291
|
+
$php_process->start_listening();
|
data/php_process.gemspec
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Generated by jeweler
|
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
|
4
|
+
# -*- encoding: utf-8 -*-
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |s|
|
|
7
|
+
s.name = %q{php_process}
|
|
8
|
+
s.version = "0.0.2"
|
|
9
|
+
|
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
|
+
s.authors = ["Kasper Johansen"]
|
|
12
|
+
s.date = %q{2012-05-05}
|
|
13
|
+
s.description = %q{Spawns a PHP process and proxies calls to it, making it possible to proxy objects and more.}
|
|
14
|
+
s.email = %q{k@spernj.org}
|
|
15
|
+
s.extra_rdoc_files = [
|
|
16
|
+
"LICENSE.txt",
|
|
17
|
+
"README.rdoc"
|
|
18
|
+
]
|
|
19
|
+
s.files = [
|
|
20
|
+
".document",
|
|
21
|
+
".rspec",
|
|
22
|
+
"Gemfile",
|
|
23
|
+
"LICENSE.txt",
|
|
24
|
+
"README.rdoc",
|
|
25
|
+
"Rakefile",
|
|
26
|
+
"VERSION",
|
|
27
|
+
"lib/php_process.rb",
|
|
28
|
+
"lib/php_script.php",
|
|
29
|
+
"php_process.gemspec",
|
|
30
|
+
"spec/php_process_spec.rb",
|
|
31
|
+
"spec/spec_helper.rb"
|
|
32
|
+
]
|
|
33
|
+
s.homepage = %q{http://github.com/kaspernj/php_process}
|
|
34
|
+
s.licenses = ["MIT"]
|
|
35
|
+
s.require_paths = ["lib"]
|
|
36
|
+
s.rubygems_version = %q{1.6.2}
|
|
37
|
+
s.summary = %q{Ruby-to-PHP bridge}
|
|
38
|
+
|
|
39
|
+
if s.respond_to? :specification_version then
|
|
40
|
+
s.specification_version = 3
|
|
41
|
+
|
|
42
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
43
|
+
s.add_runtime_dependency(%q<knjrbfw>, [">= 0"])
|
|
44
|
+
s.add_runtime_dependency(%q<php-serialize>, [">= 0"])
|
|
45
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
|
|
46
|
+
s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
|
|
47
|
+
s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
|
|
48
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
|
|
49
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
|
50
|
+
else
|
|
51
|
+
s.add_dependency(%q<knjrbfw>, [">= 0"])
|
|
52
|
+
s.add_dependency(%q<php-serialize>, [">= 0"])
|
|
53
|
+
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
|
54
|
+
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
|
55
|
+
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
|
56
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
|
|
57
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
|
58
|
+
end
|
|
59
|
+
else
|
|
60
|
+
s.add_dependency(%q<knjrbfw>, [">= 0"])
|
|
61
|
+
s.add_dependency(%q<php-serialize>, [">= 0"])
|
|
62
|
+
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
|
63
|
+
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
|
64
|
+
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
|
65
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
|
|
66
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
data/spec/php_process_spec.rb
CHANGED
|
@@ -4,12 +4,14 @@ describe "PhpProcess" do
|
|
|
4
4
|
it "should be able to start" do
|
|
5
5
|
require "timeout"
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
#Spawn PHP-process.
|
|
9
|
+
$php = Php_process.new(:debug => false, :debug_stderr => true)
|
|
8
10
|
|
|
9
11
|
|
|
10
12
|
#Test function calls without arguments.
|
|
11
13
|
pid = $php.func("getmypid")
|
|
12
|
-
raise "Invalid PID: #{
|
|
14
|
+
raise "Invalid PID: #{pid}" if pid.to_i <= 0
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
#Test function calls with arguments.
|
|
@@ -55,7 +57,7 @@ describe "PhpProcess" do
|
|
|
55
57
|
#Should be able to write 1000 rows in less than 5 sec.
|
|
56
58
|
Timeout.timeout(5) do
|
|
57
59
|
0.upto(1000) do |i|
|
|
58
|
-
tw.write_row(["test#{i}", i, "test#{i}", i.to_f])
|
|
60
|
+
#tw.write_row(["test#{i}", i, "test#{i}", i.to_f])
|
|
59
61
|
end
|
|
60
62
|
end
|
|
61
63
|
|
|
@@ -75,7 +77,7 @@ describe "PhpProcess" do
|
|
|
75
77
|
#Should be able to write 1000 rows in less than 5 sec.
|
|
76
78
|
Timeout.timeout(5) do
|
|
77
79
|
0.upto(1000) do |i|
|
|
78
|
-
tw.write_row(["test#{i}", i, "test#{i}", i.to_f])
|
|
80
|
+
#tw.write_row(["test#{i}", i, "test#{i}", i.to_f])
|
|
79
81
|
end
|
|
80
82
|
end
|
|
81
83
|
|
|
@@ -86,7 +88,50 @@ describe "PhpProcess" do
|
|
|
86
88
|
#Try some really advanced object-stuff.
|
|
87
89
|
pe = $php.new("PHPExcel")
|
|
88
90
|
pe.getProperties.setCreator("kaspernj")
|
|
91
|
+
pe.setActiveSheetIndex(0)
|
|
92
|
+
|
|
93
|
+
sheet = pe.getActiveSheet
|
|
94
|
+
|
|
95
|
+
const_border_thick = $php.constant_val("PHPExcel_Style_Border::BORDER_THICK")
|
|
96
|
+
|
|
97
|
+
sheet.getStyle("A1:C1").getBorders.getTop.setBorderStyle(const_border_thick)
|
|
98
|
+
sheet.getStyle("A1:A5").getBorders.getLeft.setBorderStyle(const_border_thick)
|
|
99
|
+
sheet.getStyle("A5:C5").getBorders.getBottom.setBorderStyle(const_border_thick)
|
|
100
|
+
sheet.getStyle("C1:C5").getBorders.getRight.setBorderStyle(const_border_thick)
|
|
101
|
+
|
|
102
|
+
sheet.setCellValue("A1", "Kasper Johansen")
|
|
103
|
+
sheet.getStyle("A1").getFont.setBold(true)
|
|
104
|
+
|
|
105
|
+
writer = $php.new("PHPExcel_Writer_Excel2007", pe)
|
|
106
|
+
writer.save("/tmp/test_excel.xlsx")
|
|
107
|
+
|
|
89
108
|
pe = nil
|
|
109
|
+
sheet = nil
|
|
110
|
+
writer = nil
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
#Try to play a little with GTK2-extension.
|
|
114
|
+
$php.func("dl", "php_gtk2.so")
|
|
115
|
+
win = $php.new("GtkWindow")
|
|
116
|
+
win.set_title("Test")
|
|
117
|
+
|
|
118
|
+
button = $php.new("GtkButton")
|
|
119
|
+
button.set_label("Weee!")
|
|
120
|
+
|
|
121
|
+
win.add(button)
|
|
122
|
+
win.show_all
|
|
123
|
+
#$php.static("Gtk", "main")
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
#Test ability to create functions and do callbacks.
|
|
127
|
+
$callback_from_php = "test"
|
|
128
|
+
func = $php.create_func do |arg|
|
|
129
|
+
$callback_from_php = arg
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
#Send argument 'kasper' which will be what "$callback_from_php" will be changed to.
|
|
133
|
+
func.call("kasper")
|
|
134
|
+
raise "Expected callback from PHP to change variable but it didnt: '#{$callback_from_php}'." if $callback_from_php != "kasper"
|
|
90
135
|
|
|
91
136
|
|
|
92
137
|
#Check garbage collection, cache and stuff.
|
|
@@ -100,4 +145,4 @@ describe "PhpProcess" do
|
|
|
100
145
|
#Destroy the object.
|
|
101
146
|
$php.destroy
|
|
102
147
|
end
|
|
103
|
-
end
|
|
148
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: php_process
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.2
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,12 +9,12 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2012-05-
|
|
12
|
+
date: 2012-05-05 00:00:00.000000000 +02:00
|
|
13
13
|
default_executable:
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: knjrbfw
|
|
17
|
-
requirement: &
|
|
17
|
+
requirement: &18683880 !ruby/object:Gem::Requirement
|
|
18
18
|
none: false
|
|
19
19
|
requirements:
|
|
20
20
|
- - ! '>='
|
|
@@ -22,10 +22,10 @@ dependencies:
|
|
|
22
22
|
version: '0'
|
|
23
23
|
type: :runtime
|
|
24
24
|
prerelease: false
|
|
25
|
-
version_requirements: *
|
|
25
|
+
version_requirements: *18683880
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: php-serialize
|
|
28
|
-
requirement: &
|
|
28
|
+
requirement: &18682760 !ruby/object:Gem::Requirement
|
|
29
29
|
none: false
|
|
30
30
|
requirements:
|
|
31
31
|
- - ! '>='
|
|
@@ -33,10 +33,10 @@ dependencies:
|
|
|
33
33
|
version: '0'
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
|
-
version_requirements: *
|
|
36
|
+
version_requirements: *18682760
|
|
37
37
|
- !ruby/object:Gem::Dependency
|
|
38
38
|
name: rspec
|
|
39
|
-
requirement: &
|
|
39
|
+
requirement: &18681580 !ruby/object:Gem::Requirement
|
|
40
40
|
none: false
|
|
41
41
|
requirements:
|
|
42
42
|
- - ~>
|
|
@@ -44,10 +44,10 @@ dependencies:
|
|
|
44
44
|
version: 2.8.0
|
|
45
45
|
type: :development
|
|
46
46
|
prerelease: false
|
|
47
|
-
version_requirements: *
|
|
47
|
+
version_requirements: *18681580
|
|
48
48
|
- !ruby/object:Gem::Dependency
|
|
49
49
|
name: rdoc
|
|
50
|
-
requirement: &
|
|
50
|
+
requirement: &18680980 !ruby/object:Gem::Requirement
|
|
51
51
|
none: false
|
|
52
52
|
requirements:
|
|
53
53
|
- - ~>
|
|
@@ -55,10 +55,10 @@ dependencies:
|
|
|
55
55
|
version: '3.12'
|
|
56
56
|
type: :development
|
|
57
57
|
prerelease: false
|
|
58
|
-
version_requirements: *
|
|
58
|
+
version_requirements: *18680980
|
|
59
59
|
- !ruby/object:Gem::Dependency
|
|
60
60
|
name: bundler
|
|
61
|
-
requirement: &
|
|
61
|
+
requirement: &18679700 !ruby/object:Gem::Requirement
|
|
62
62
|
none: false
|
|
63
63
|
requirements:
|
|
64
64
|
- - ! '>='
|
|
@@ -66,10 +66,10 @@ dependencies:
|
|
|
66
66
|
version: 1.0.0
|
|
67
67
|
type: :development
|
|
68
68
|
prerelease: false
|
|
69
|
-
version_requirements: *
|
|
69
|
+
version_requirements: *18679700
|
|
70
70
|
- !ruby/object:Gem::Dependency
|
|
71
71
|
name: jeweler
|
|
72
|
-
requirement: &
|
|
72
|
+
requirement: &18678820 !ruby/object:Gem::Requirement
|
|
73
73
|
none: false
|
|
74
74
|
requirements:
|
|
75
75
|
- - ~>
|
|
@@ -77,10 +77,10 @@ dependencies:
|
|
|
77
77
|
version: 1.8.3
|
|
78
78
|
type: :development
|
|
79
79
|
prerelease: false
|
|
80
|
-
version_requirements: *
|
|
80
|
+
version_requirements: *18678820
|
|
81
81
|
- !ruby/object:Gem::Dependency
|
|
82
82
|
name: rcov
|
|
83
|
-
requirement: &
|
|
83
|
+
requirement: &18677920 !ruby/object:Gem::Requirement
|
|
84
84
|
none: false
|
|
85
85
|
requirements:
|
|
86
86
|
- - ! '>='
|
|
@@ -88,7 +88,7 @@ dependencies:
|
|
|
88
88
|
version: '0'
|
|
89
89
|
type: :development
|
|
90
90
|
prerelease: false
|
|
91
|
-
version_requirements: *
|
|
91
|
+
version_requirements: *18677920
|
|
92
92
|
description: Spawns a PHP process and proxies calls to it, making it possible to proxy
|
|
93
93
|
objects and more.
|
|
94
94
|
email: k@spernj.org
|
|
@@ -107,6 +107,7 @@ files:
|
|
|
107
107
|
- VERSION
|
|
108
108
|
- lib/php_process.rb
|
|
109
109
|
- lib/php_script.php
|
|
110
|
+
- php_process.gemspec
|
|
110
111
|
- spec/php_process_spec.rb
|
|
111
112
|
- spec/spec_helper.rb
|
|
112
113
|
has_rdoc: true
|
|
@@ -125,7 +126,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
125
126
|
version: '0'
|
|
126
127
|
segments:
|
|
127
128
|
- 0
|
|
128
|
-
hash: -
|
|
129
|
+
hash: -656564048361745716
|
|
129
130
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
130
131
|
none: false
|
|
131
132
|
requirements:
|