Class: Php_process
- Inherits:
-
Object
- Object
- Php_process
- Defined in:
- lib/php_process.rb
Overview
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.
Examples
php = Php_process.new print “PID of PHP-process: #phpphp.func(”getmypid“)n” print “Explode test: #”;“, ”1;2;3;4;5“)n”
Defined Under Namespace
Classes: Created_function, Proxy_obj
Instance Attribute Summary collapse
-
#object_ids ⇒ Object
readonly
A hash that contains links between Ruby object IDs and the PHP object IDs.
Class Method Summary collapse
-
.path ⇒ Object
Returns the path to the gem.
Instance Method Summary collapse
-
#constant_val(name) ⇒ Object
Returns the value of a constant on the PHP-side.
-
#create_func(args = {}, &block) ⇒ Object
Creates a function on the PHP-side.
-
#destroy ⇒ Object
Destroys the object closing and unsetting everything.
-
#eval(eval_str) ⇒ Object
Evaluates a string containing PHP-code and returns the result.
-
#flush_unset_ids(force = false) ⇒ Object
This flushes the unset IDs to the PHP-process and frees memory.
-
#func(func_name, *args) ⇒ Object
Call a function in PHP.
-
#initialize(args = {}) ⇒ Php_process
constructor
Spawns various used variables, launches the process and more.
-
#join ⇒ Object
Joins all the threads.
-
#memory_info ⇒ Object
Returns various informations about boths sides memory in a hash.
-
#new(classname, *args) ⇒ Object
Spawns a new object from a given class with given arguments and returns it.
-
#object_cache_info ⇒ Object
Returns various info in a hash about the object-cache on the PHP-side.
-
#objects_unsetter(id) ⇒ Object
This object controls which IDs should be unset on the PHP-side by being a destructor on the Ruby-side.
-
#parse_data(data) ⇒ Object
Parses argument-data into special hashes that can be used on the PHP-side.
-
#send(hash) ⇒ Object
Proxies to ‘send_real’ but calls ‘flush_unset_ids’ first.
-
#static(class_name, method_name, *args) ⇒ Object
Sends a call to a static method on a class with given arguments.
Constructor Details
#initialize(args = {}) ⇒ Php_process
Spawns various used variables, launches the process and more.
Examples
If you want debugging printed to stderr: php = Php_process.new(:debug => true)
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/php_process.rb', line 37 def initialize(args = {}) @args = args @debug = @args[:debug] @send_count = 0 @send_mutex = Mutex.new @responses = Tsafe::MonHash.new @object_ids = Tsafe::MonHash.new @object_unset_ids = Tsafe::MonArray.new @objects = Wref_map.new @constant_val_cache = Tsafe::MonHash.new #Used for 'create_func'. @callbacks = {} @callbacks_count = 0 @callbacks_mutex = Mutex.new if @args[:cmd_php] cmd_str = "#{@args[:cmd_php]} " else cmd_str = "/usr/bin/env php5 " end cmd_str << "\"#{File.dirname(__FILE__)}/php_script.php\"" if RUBY_ENGINE == "jruby" pid, @stdin, @stdout, @stderr = IO.popen4(cmd_str) else @stdin, @stdout, @stderr = Open3.popen3(cmd_str) end @stdout.sync = true @stdin.sync = true @stdin.set_encoding("iso-8859-1:utf-8") #@stderr.set_encoding("utf-8:iso-8859-1") @stdout.set_encoding("utf-8:iso-8859-1") @err_thread = Thread.new do begin @stderr.each_line do |str| @args[:on_err].call(str) if @args[:on_err] $stderr.print "Process error: #{str}" if @debug or @args[:debug_stderr] if str.match(/^PHP Fatal error: (.+)\s*/) @fatal = str.strip elsif str.match(/^Killed\s*$/) @fatal = "Process was killed." end break if (!@args and str.to_s.strip.length <= 0) or (@stderr and @stderr.closed?) end rescue => e $stderr.puts e.inspect $stderr.puts e.backtrace end end $stderr.print "Waiting for PHP-script to be ready.\n" if @debug started = false @stdout.lines do |line| if match = line.match(/^php_script_ready:(\d+)\n/) started = true break end $stderr.print "Line gotten while waiting: #{line}" if @debug end raise "PHP process wasnt started." if !started check_alive $stderr.print "PHP-script ready.\n" if @debug start_read_loop if block_given? begin yield(self) ensure self.destroy end end end |
Instance Attribute Details
#object_ids ⇒ Object (readonly)
A hash that contains links between Ruby object IDs and the PHP object IDs. It can be read because the proxy-objects adds their data to it.
20 21 22 |
# File 'lib/php_process.rb', line 20 def object_ids @object_ids end |
Class Method Details
.path ⇒ Object
Returns the path to the gem.
15 16 17 |
# File 'lib/php_process.rb', line 15 def self.path return File.realpath(File.dirname(__FILE__)) end |
Instance Method Details
#constant_val(name) ⇒ Object
Returns the value of a constant on the PHP-side.
252 253 254 255 256 257 258 259 260 |
# File 'lib/php_process.rb', line 252 def constant_val(name) const_name = name.to_s if !@constant_val_cache.key?(const_name) @constant_val_cache[const_name] = self.send(:type => :constant_val, :name => name) end return @constant_val_cache[const_name] end |
#create_func(args = {}, &block) ⇒ Object
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.
Examples
func = php.create_func do |d|
d.php.static("Gtk", "main_quit")
end
button.connect(“clicked”, func)
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/php_process.rb', line 196 def create_func(args = {}, &block) callback_id = nil func = nil @callbacks_mutex.synchronize do callback_id = @callbacks_count func = Php_process::Created_function.new(:php => self, :id => callback_id) @callbacks[callback_id] = {:block => block, :func => func, :id => callback_id} @callbacks_count += 1 end raise "No callback-ID?" if !callback_id self.send(:type => :create_func, :callback_id => callback_id) return func end |
#destroy ⇒ Object
Destroys the object closing and unsetting everything.
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/php_process.rb', line 135 def destroy @thread.kill if @thread @err_thread.kill if @err_thread @stdout.close if @stdout @stdin.close if @stdin @stderr.close if @stderr @thread = nil @err_thread = nil @fatal = nil @responses = nil @object_ids = nil @object_unset_ids = nil @send_count = nil @args = nil @debug = nil end |
#eval(eval_str) ⇒ Object
Evaluates a string containing PHP-code and returns the result.
Examples
print php.eval(“array(1 => 2);”) #=> 1=>2
161 162 163 |
# File 'lib/php_process.rb', line 161 def eval(eval_str) return self.send(:type => :eval, :eval_str => eval_str) end |
#flush_unset_ids(force = false) ⇒ Object
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.
Examples
php.flush_unset_ids(true)
215 216 217 218 219 220 221 222 223 224 |
# File 'lib/php_process.rb', line 215 def flush_unset_ids(force = false) return nil if !force and @object_unset_ids.length < 500 while @object_unset_ids.length > 0 and elements = @object_unset_ids.shift(500) $stderr.print "Sending unsets: #{elements}\n" if @debug send_real("type" => "unset_ids", "ids" => elements) end #Clean wref-map. @objects.clean end |
#func(func_name, *args) ⇒ Object
Call a function in PHP.
Examples
arr = php.func(“explode”, “;”, “1;2;3;4;5”) pid_of_php_process = php.func(“getmypid”) php.func(“require_once”, “PHPExcel.php”)
178 179 180 |
# File 'lib/php_process.rb', line 178 def func(func_name, *args) return self.send(:type => :func, :func_name => func_name, :args => parse_data(args)) end |
#join ⇒ Object
Joins all the threads.
129 130 131 132 |
# File 'lib/php_process.rb', line 129 def join @thread.join if @thread @err_thread.join if @err_thread end |
#memory_info ⇒ Object
Returns various informations about boths sides memory in a hash.
263 264 265 266 267 268 269 270 271 272 273 |
# File 'lib/php_process.rb', line 263 def memory_info return { :php_info => self.send(:type => :memory_info), :ruby_info => { :responses => @responses.length, :objects_ids => @object_ids.length, :object_unset_ids => @object_unset_ids.length, :objects => @objects.length } } end |
#new(classname, *args) ⇒ Object
Spawns a new object from a given class with given arguments and returns it.
Examples
pe = php.new(“PHPExcel”) pe.getProperties.setCreator(“kaspernj”)
169 170 171 |
# File 'lib/php_process.rb', line 169 def new(classname, *args) return self.send(:type => :new, :class => classname, :args => parse_data(args)) end |
#object_cache_info ⇒ Object
Returns various info in a hash about the object-cache on the PHP-side.
124 125 126 |
# File 'lib/php_process.rb', line 124 def object_cache_info return self.send(:type => :object_cache_info) end |
#objects_unsetter(id) ⇒ Object
This object controls which IDs should be unset on the PHP-side by being a destructor on the Ruby-side.
23 24 25 26 27 28 29 30 31 |
# File 'lib/php_process.rb', line 23 def objects_unsetter(id) obj_count_id = @object_ids[id] if @object_unset_ids.index(obj_count_id) == nil @object_unset_ids << obj_count_id end @object_ids.delete(id) end |
#parse_data(data) ⇒ Object
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.
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
# File 'lib/php_process.rb', line 227 def parse_data(data) if data.is_a?(Php_process::Proxy_obj) return {:type => :proxyobj, :id => data.args[:id]} elsif data.is_a?(Php_process::Created_function) return {:type => :php_process_created_function, :id => data.args[:id]} elsif data.is_a?(Hash) newhash = {} data.each do |key, val| newhash[key] = parse_data(val) end return newhash elsif data.is_a?(Array) newarr = [] data.each do |val| newarr << parse_data(val) end return newarr else return data end end |
#send(hash) ⇒ Object
Proxies to ‘send_real’ but calls ‘flush_unset_ids’ first.
153 154 155 156 |
# File 'lib/php_process.rb', line 153 def send(hash) self.flush_unset_ids return send_real(hash) end |
#static(class_name, method_name, *args) ⇒ Object
Sends a call to a static method on a class with given arguments.
Examples
php.static(“Gtk”, “main_quit”)
185 186 187 |
# File 'lib/php_process.rb', line 185 def static(class_name, method_name, *args) return self.send(:type => :static_method_call, :class_name => class_name, :method_name => method_name, :args => parse_data(args)) end |