Type Definition ext_php_rs::types::ZendObject

source ·
pub type ZendObject = zend_object;
Expand description

A PHP object.

This type does not maintain any information about its type, for example, classes with have associated Rust structs cannot be accessed through this type. ZendClassObject is used for this purpose, and you can convert between the two.

Implementations§

Creates a new ZendObject, returned inside an ZBox<ZendObject> wrapper.

Parameters
  • ce - The type of class the new object should be an instance of.
Panics

Panics when allocating memory for the new object fails.

Examples found in repository?
src/types/object.rs (line 72)
69
70
71
72
73
    pub fn new_stdclass() -> ZBox<Self> {
        // SAFETY: This will be `NULL` until it is initialized. `as_ref()` checks for
        // null, so we can panic if it's null.
        Self::new(ce::stdclass())
    }

Creates a new stdClass instance, returned inside an ZBox<ZendObject> wrapper.

Panics

Panics if allocating memory for the object fails, or if the stdClass class entry has not been registered with PHP yet.

Example
use ext_php_rs::types::ZendObject;

let mut obj = ZendObject::new_stdclass();

obj.set_property("hello", "world");

Converts a class object into an owned ZendObject. This removes any possibility of accessing the underlying attached Rust struct.

Examples found in repository?
src/types/object.rs (line 364)
363
364
365
    fn from(obj: ZBox<ZendClassObject<T>>) -> Self {
        ZendObject::from_class_object(obj)
    }
source

pub fn get_class_entry(&self) -> &'static ClassEntry

Returns the ClassEntry associated with this object.

Panics

Panics if the class entry is invalid.

Examples found in repository?
src/types/object.rs (line 113)
112
113
114
    pub fn instance_of(&self, ce: &ClassEntry) -> bool {
        self.get_class_entry().instance_of(ce)
    }

Attempts to retrieve the class name of the object.

Examples found in repository?
src/types/object.rs (line 270)
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let mut dbg = f.debug_struct(
            self.get_class_name()
                .unwrap_or_else(|_| "ZendObject".to_string())
                .as_str(),
        );

        if let Ok(props) = self.get_properties() {
            for (id, key, val) in props.iter() {
                dbg.field(key.unwrap_or_else(|| id.to_string()).as_str(), val);
            }
        }

        dbg.finish()
    }
}

impl<'a> FromZval<'a> for &'a ZendObject {
    const TYPE: DataType = DataType::Object(None);

    fn from_zval(zval: &'a Zval) -> Option<Self> {
        zval.object()
    }
}

impl<'a> FromZvalMut<'a> for &'a mut ZendObject {
    const TYPE: DataType = DataType::Object(None);

    fn from_zval_mut(zval: &'a mut Zval) -> Option<Self> {
        zval.object_mut()
    }
}

impl IntoZval for ZBox<ZendObject> {
    const TYPE: DataType = DataType::Object(None);

    #[inline]
    fn set_zval(mut self, zv: &mut Zval, _: bool) -> Result<()> {
        // We must decrement the refcounter on the object before inserting into the
        // zval, as the reference counter will be incremented on add.
        // NOTE(david): again is this needed, we increment in `set_object`.
        self.dec_count();
        zv.set_object(self.into_raw());
        Ok(())
    }
}

impl<'a> IntoZval for &'a mut ZendObject {
    const TYPE: DataType = DataType::Object(None);

    #[inline]
    fn set_zval(self, zv: &mut Zval, _: bool) -> Result<()> {
        zv.set_object(self);
        Ok(())
    }
}

impl FromZendObject<'_> for String {
    fn from_zend_object(obj: &ZendObject) -> Result<Self> {
        let mut ret = Zval::new();
        unsafe {
            zend_call_known_function(
                (*obj.ce).__tostring,
                obj as *const _ as *mut _,
                obj.ce,
                &mut ret,
                0,
                std::ptr::null_mut(),
                std::ptr::null_mut(),
            );
        }

        if let Some(err) = ExecutorGlobals::take_exception() {
            // TODO: become an error
            let class_name = obj.get_class_name();
            panic!(
                "Uncaught exception during call to {}::__toString(): {:?}",
                class_name.expect("unable to determine class name"),
                err
            );
        } else if let Some(output) = ret.extract() {
            Ok(output)
        } else {
            // TODO: become an error
            let class_name = obj.get_class_name();
            panic!(
                "{}::__toString() must return a string",
                class_name.expect("unable to determine class name"),
            );
        }
    }

Returns whether this object is an instance of the given ClassEntry.

This method checks the class and interface inheritance chain.

Panics

Panics if the class entry is invalid.

Checks if the given object is an instance of a registered class with Rust type T.

This method doesn’t check the class and interface inheritance chain.

Examples found in repository?
src/types/class_object.rs (line 169)
162
163
164
165
166
167
168
169
170
171
172
173
174
    fn _from_zend_obj(std: &zend_object) -> Option<&mut Self> {
        let std = std as *const zend_object as *const i8;
        let ptr = unsafe {
            let ptr = std.offset(0 - Self::std_offset() as isize) as *const Self;
            (ptr as *mut Self).as_mut()?
        };

        if ptr.std.is_instance::<T>() {
            Some(ptr)
        } else {
            None
        }
    }

Attempts to read a property from the Object. Returns a result containing the value of the property if it exists and can be read, and an Error otherwise.

Parameters
  • name - The name of the property.
  • query - The type of query to use when attempting to get a property.

Attempts to set a property on the object.

Parameters
  • name - The name of the property.
  • value - The value to set the property to.

Checks if a property exists on an object. Takes a property name and query parameter, which defines what classifies if a property exists or not. See PropertyQuery for more information.

Parameters
  • name - The name of the property.
  • query - The ‘query’ to classify if a property exists.
Examples found in repository?
src/types/object.rs (line 136)
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
    pub fn get_property<'a, T>(&'a self, name: &str) -> Result<T>
    where
        T: FromZval<'a>,
    {
        if !self.has_property(name, PropertyQuery::Exists)? {
            return Err(Error::InvalidProperty);
        }

        let mut name = ZendStr::new(name, false);
        let mut rv = Zval::new();

        let zv = unsafe {
            self.handlers()?.read_property.ok_or(Error::InvalidScope)?(
                self.mut_ptr(),
                name.deref_mut(),
                1,
                std::ptr::null_mut(),
                &mut rv,
            )
            .as_ref()
        }
        .ok_or(Error::InvalidScope)?;

        T::from_zval(zv).ok_or_else(|| Error::ZvalConversion(zv.get_type()))
    }

Attempts to retrieve the properties of the object. Returned inside a Zend Hashtable.

Examples found in repository?
src/types/object.rs (line 275)
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let mut dbg = f.debug_struct(
            self.get_class_name()
                .unwrap_or_else(|_| "ZendObject".to_string())
                .as_str(),
        );

        if let Ok(props) = self.get_properties() {
            for (id, key, val) in props.iter() {
                dbg.field(key.unwrap_or_else(|| id.to_string()).as_str(), val);
            }
        }

        dbg.finish()
    }

Extracts some type from a Zend object.

This is a wrapper function around FromZendObject::extract().

Returns an unique identifier for the object.

The id is guaranteed to be unique for the lifetime of the object. Once the object is destroyed, it may be reused for other objects. This is equivalent to calling the spl_object_id PHP function.

Computes an unique hash for the object.

The hash is guaranteed to be unique for the lifetime of the object. Once the object is destroyed, it may be reused for other objects. This is equivalent to calling the spl_object_hash PHP function.

Trait Implementations§

Formats the value using the given formatter. Read more
The corresponding type of the implemented value in PHP.
Attempts to retrieve an instance of Self from a reference to a Zval. Read more
The corresponding type of the implemented value in PHP.
Attempts to retrieve an instance of Self from a mutable reference to a Zval. Read more
The corresponding type of the implemented value in PHP.
Sets the content of a pre-existing zval. Returns a result containing nothing if setting the content was successful. Read more
Converts a Rust primitive type into a Zval. Returns a result containing the Zval if successful. Read more
Returns an immutable reference to the corresponding refcount object.
Returns a mutable reference to the corresponding refcount object.
Returns the number of references to the object.
Increments the reference counter by 1.
Decrements the reference counter by 1.
Frees the memory pointed to by self, calling any destructors required in the process.