php_process 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|