Derive Macro ext_php_rs::ZvalConvert [−][src]
#[derive(ZvalConvert)]Expand description
Derives the traits required to convert a struct or enum to and from a Zval.
Both FromZval and IntoZval are implemented on types which use this macro.
Structs
When the macro is used on a struct, the FromZendObject and IntoZendObject traits are also
implemented, and will attempt to retrieve values for the struct fields from the objects properties.
This can be useful when you expect some arbitrary object (of which the type does not matter), but
you care about the value of the properties.
All properties must implement FromZval and IntoZval themselves. Generics are supported,
however, a FromZval and IntoZval bound will be added. If one property cannot be retrieved
from the object, the whole conversion will fail.
Examples
Basic example with some primitive PHP type.
#[derive(Debug, ZvalConvert)]
pub struct ExampleStruct<'a> {
a: i32,
b: String,
c: &'a str
}
#[php_function]
pub fn take_object(obj: ExampleStruct) {
dbg!(obj);
}
#[php_function]
pub fn give_object() -> ExampleStruct<'static> {
ExampleStruct {
a: 5,
b: "Hello, world!".into(),
c: "Static string",
}
}Can be used in PHP:
$obj = (object) [
'a' => 5,
'b' => 'Hello, world!',
'c' => 'asdf',
];
take_object($obj);
var_dump(give_object());Another example involving generics:
#[derive(Debug, ZvalConvert)]
pub struct CompareVals<T: PartialEq<i32>> {
a: T,
b: T
}
#[php_function]
pub fn take_object(obj: CompareVals<i32>) {
dbg!(obj);
}Enums
When the macro is used on an enum, the FromZval and IntoZval implementations will treat
the enum as a tagged union with a mixed datatype. This allows you to accept two different types
in a parameter, for example, a string and an integer.
The enum variants must not have named fields (i.e. not in the form of a struct), and must have
exactly one field, the type to extract from the Zval. Optionally, the enum may have a
single default, empty variant, which is used when the Zval did not contain any data to fill
the other variants. This empty variant is equivalent to null in PHP.
The ordering of the enum variants is important, as the Zval contents is matched in order of
the variants. For example, Zval::string will attempt to read a string from the Zval,
and if the Zval contains a long, the long will be converted to a string. If a string
variant was placed above an integer variant in the enum, the integer would be converted into a
string and passed as the string variant.
Examples
Basic example showing the importance of variant ordering and default field:
#[derive(Debug, ZvalConvert)]
pub enum UnionExample<'a> {
Long(u64), // Long
ProperStr(&'a str), // Actual string - not a converted value
ParsedStr(String), // Potentially parsed string, i.e. a double
None // Zval did not contain anything that could be parsed above
}
#[php_function]
pub fn test_union(val: UnionExample) {
dbg!(val);
}
#[php_function]
pub fn give_union() -> UnionExample<'static> {
UnionExample::Long(5)
}Use in PHP:
test_union(5); // UnionExample::Long(5)
test_union("Hello, world!"); // UnionExample::ProperStr("Hello, world!")
test_union(5.66666); // UnionExample::ParsedStr("5.6666")
test_union(null); // UnionExample::None
var_dump(give_union()); // int(5)