Expand description
§Zval
Refer to: https://www.phpinternalsbook.com/php7/zvals/basic_structure.html#the-zval-struct
A zval (short for “Zend value”) represents an arbitrary PHP value. As such it is likely the most important structure in all of PHP and you’ll be working with it a lot.
The phper::values::ZVal is the wrapper of php zval.
§Actual type of ZVal
PHP is a dynamically typed language, zval can represent multiple types,
but there is only one type at a time, you can use
phper::values::ZVal::get_type_info to get the actual type.
§Convert Rust type to ZVal
The phper::values::ZVal implements a lot of std::convert::From for the
conversion.
Here is the mapping of relationships between Rust types and base PHP types.
| Trait | Rust type | PHP type |
|---|---|---|
From<()> | () | null |
From<bool> | bool | bool |
From<i64> | i64 | long |
From<f64> | f64 | double |
From<&str> | &str | string |
From<&CStr> | &CStr | string |
From<&[u8]> | &[u8] | string |
From<Vec<u8>> | Vec<u8> | string |
From<ZString> | phper::strings::ZString | string |
From<ZArray> | phper::arrays::ZArray | array |
From<ZObject> | phper::objects::ZObject | object |
There are also composite types that implement From.
From<Option<T>>: if Some(T), T will be converted to PHP type likeFrom<T>, orNonewill be converted tonull.
use phper::values::ZVal;
assert!(ZVal::from(()).get_type_info().is_null());
assert!(ZVal::from(100i64).get_type_info().is_long());§Convert ZVal to Rust type
Now you can use as_* or expect_* methods to convert ZVal to Rust types.
-
The
as_*returnsOption<T>. -
The
expect_*returnsphper::Result<T>, if convert failed, phper::errors::ExpectTypeError will be returned, with the message:type error: must be of type {expect_type}, {actual_type} given").
use phper::echo;
use phper::values::ZVal;
fn say_hello(arguments: &mut [ZVal]) -> phper::Result<()> {
// Get the first argument, expect the type `ZStr`, and convert to Rust utf-8
// str.
let name = arguments[0].expect_z_str()?.to_str()?;
// Macro which runs PHP internal function `echo`.
echo!("Hello, {}!\n", name);
Ok(())
}§Value copy & reference counting copy
The phper::values::ZVal both implements std::clone::Clone and
phper::alloc::RefClone.
-
std::clone::Clone: represent value copy (Type ZObject is excluded because it is always passed by reference). -
phper::alloc::RefClone: represent reference counting copy (Type (), bool, i64, f64 is excluded because they are not reference counting types).
§PHP internal cast
Refer to: https://www.phpinternalsbook.com/php7/zvals/casts_and_operations.html#casts
PHP is a weakly typed language, yet it supports type casting internally.
The zend engine provides convert_to_* functions to do the type cast, and
ZVal wraps them directly.
§Callable
The phper::values::ZVal can be called via phper::values::ZVal::call. Make
sure that the actual type is callable (string, array or closure).
use phper::values::ZVal;
use phper::arrays::ZArray;
let mut arr = ZArray::new();
arr.insert("a", ZVal::from(1));
arr.insert("b", ZVal::from(2));
let ret = ZVal::from("json_encode").call(&mut [ZVal::from(arr)]).unwrap();
assert_eq!(ret.expect_z_str().unwrap().to_str(), Ok(r#"{"a":1,"b":2}"#));