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.
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)
31 32 33 34 35 36 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 |
# File 'lib/php_process.rb', line 31 def initialize(args = {}) @args = args @debug = @args[:debug] @send_count = 0 @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.
14 15 16 |
# File 'lib/php_process.rb', line 14 def object_ids @object_ids end |
Instance Method Details
#constant_val(name) ⇒ Object
Returns the value of a constant on the PHP-side.
245 246 247 248 249 250 251 252 253 |
# File 'lib/php_process.rb', line 245 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)
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/php_process.rb', line 189 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.
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/php_process.rb', line 128 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
154 155 156 |
# File 'lib/php_process.rb', line 154 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)
208 209 210 211 212 213 214 215 216 217 |
# File 'lib/php_process.rb', line 208 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”)
171 172 173 |
# File 'lib/php_process.rb', line 171 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.
122 123 124 125 |
# File 'lib/php_process.rb', line 122 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.
256 257 258 259 260 261 262 263 264 265 266 |
# File 'lib/php_process.rb', line 256 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”)
162 163 164 |
# File 'lib/php_process.rb', line 162 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.
117 118 119 |
# File 'lib/php_process.rb', line 117 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.
17 18 19 20 21 22 23 24 25 |
# File 'lib/php_process.rb', line 17 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.
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/php_process.rb', line 220 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.
146 147 148 149 |
# File 'lib/php_process.rb', line 146 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”)
178 179 180 |
# File 'lib/php_process.rb', line 178 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 |