ext-php-rs
ext-php-rs copied to clipboard
what is the correct way to call a method of php object?
there is a similar issue https://github.com/davidcole1340/ext-php-rs/issues/193, I followed its example, but don't get lucky.
here is what I tried
pub fn render(#[this] this: &mut ZendClassObject<Template>, vars: &mut ZendObject) -> String {
dbg!(&vars.get_properties().unwrap());
let o = vars.get_property::<&ZendObject>("t").unwrap();
let callable = Zval::new();
callable.set_array(vec![o, "hello"]); // this line won't work, because
// o is &ZendObject, I can't convert it to Zval. I don't know why the example works.
let arguments = vec![];
if let Ok(result) = callable.try_call(arguments) {
dbg!(result);
}
let vars = ZendObjectView(vars);
return this.template.render(&vars).unwrap();
}
class T {
public function hello()
{
return "hello";
}
}
$t = new T();
$vars = new stdClass();
$vars->name = 'David';
$vars->age = 18;
$vars->t = $t;
Why all that fussy?
Is there an easy way to call object method?
If you're going to make repeated calls to a method, the correct (and tedious) way is to fetch the zend_function pointer from the get_method object handler, then use zend_call_known_function. This allows to store the function pointer and avoids unnecessary lookups. You can read the source for ZendObject::get_property() to get an idea of how to fetch object handlers.
If it's just for a one-of, then the call_user_func! macro of Zval::try_call() is definitely easier.
There's also zend_call_method_if_exists and zend_call_known_instance_method, but they are not exposed in the bindings, so you'll have to declare them yourself.