Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling arbitrary PHP class object methods #193

Closed
AshleySchaeffer opened this issue Nov 23, 2022 · 4 comments
Closed

Calling arbitrary PHP class object methods #193

AshleySchaeffer opened this issue Nov 23, 2022 · 4 comments

Comments

@AshleySchaeffer
Copy link

AshleySchaeffer commented Nov 23, 2022

Figured I'd raise a separate issue for clarity (see #192 ).

Is it possible to call methods on arbitrary PHP class objects, and if so how? I can't find any examples or docs pertaining to this but I could be missing something.

Essentially, I'd like to be able to take a ZendObject as a function parameter and call it's methods to retrieve output. I'm wondering if I need to define a replica php_class decorated struct, that would wrap the object and then leverage something like the call_user_func macro to call it's the methods. I'm unsure how to then approach marshalling the data returned from the object methods (which mostly strings in my case).

I'm really not sure how to approach this if it's possible. Any guidance would be greatly appreciated.

@ju1ius
Copy link
Contributor

ju1ius commented Nov 23, 2022

At the moment the only "ergonomic" way is to either use the call_user_func! macro, or the Zval::try_call() method.

I you have a reference to a ZendObject that would look like this (give or take)

let obj: &ZendObject = ...;
let callable = Zval::new();
callable.set_array(vec![obj, "methodToCall"]);
let arguments = vec![];
if let Ok(result) = zv.try_call(arguments) {
    ...
}

@AshleySchaeffer
Copy link
Author

Yeah I think that's more trouble than it's worth for my use case. Thanks for the example, just tried it and it seems to be working as expected.

@videni
Copy link

videni commented Apr 26, 2023

@ju1ius @AshleySchaeffer

where is the zv variable from please?

I tried this

        let obj: &ZendObject = ...;

        let callable = Zval::new();
        callable.set_array(vec![o, "hello"]);  // this line won't work, because  the method "hello" is type &str, not ZendObject, I don't know why the example works.

        let arguments = vec![];
        if let Ok(result) = callable.try_call(arguments) {
          dbg!(result);
        }

@ju1ius
Copy link
Contributor

ju1ius commented Apr 27, 2023

callable.set_array(vec![o, "hello"]);

Yes, this obviously doesn't work because you can't make a Vec from different types.

So either:

callable.set_array(vec![o.into_zval(false)?, "hello".into_zval(false)?]);

Or, avoiding the temporary Vec allocation:

let mut array = ZendHashTable::with_capacity(2);
array.push(my_object)?;
array.push("hello")?;
let result = array.into_zval(false)?.try_call(arguments)?;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants