ext-php-rs icon indicating copy to clipboard operation
ext-php-rs copied to clipboard

what is the correct way to call a method of php object?

Open videni opened this issue 2 years ago • 1 comments

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?

videni avatar Apr 26 '23 08:04 videni

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.

ju1ius avatar Apr 27 '23 20:04 ju1ius