In PHP, data is stored in containers called zvals (zend values). Internally, these are effectively tagged unions (enums in Rust) without the safety that Rust introduces. Passing data between Rust and PHP requires the data to become a zval. This is done through two traits: FromZval and IntoZval. These traits have been implemented on most regular Rust types:

  • Primitive integers (i8, i16, i32, i64, u8, u16, u32, u64, usize, isize).
  • Double and single-precision floating point numbers (f32, f64).
  • Booleans.
  • Strings (String and &str)
  • Vec<T> where T implements IntoZval and/or FromZval.
  • HashMap<String, T> where T implements IntoZval and/or FromZval.
  • Binary<T> where T implements Pack, used for transferring binary string data.
  • BinarySlice<T> where T implements Pack, used for exposing PHP binary strings as read-only slices.
  • A PHP callable closure or function wrapped with Callable.
  • Option<T> where T implements IntoZval and/or FromZval, and where None is converted to a PHP null.

Return types can also include:

  • Any class type which implements RegisteredClass (i.e. any struct you have registered with PHP).
  • An immutable reference to self when used in a method, through the ClassRef type.
  • A Rust closure wrapped with Closure.
  • Result<T, E>, where T: IntoZval and E: Into<PhpException>. When the error variant is encountered, it is converted into a PhpException and thrown as an exception.

For a type to be returnable, it must implement IntoZval, while for it to be valid as a parameter, it must implement FromZval.