pub fn register(mut self) -> Result<()> {
        self.ce.name = ZendStr::new_interned(&self.name, true).into_raw();

        let mut methods = self
            .methods
            .into_iter()
            .map(|(method, flags)| {
                method.build().map(|mut method| {
                    method.flags |= flags.bits();
                    method
                })
            })
            .collect::<Result<Vec<_>>>()?;

        methods.push(FunctionEntry::end());
        let func = Box::into_raw(methods.into_boxed_slice()) as *const FunctionEntry;
        self.ce.info.internal.builtin_functions = func;

        let class = unsafe {
            zend_register_internal_class_ex(
                &mut self.ce,
                match self.extends {
                    Some((ptr, _)) => ptr::from_ref(ptr()).cast_mut(),
                    None => std::ptr::null_mut(),
                },
            )
            .as_mut()
            .ok_or(Error::InvalidPointer)?
        };

        // disable serialization if the class has an associated object
        if self.object_override.is_some() {
            cfg_if::cfg_if! {
                if #[cfg(php81)] {
                    class.ce_flags |= ClassFlags::NotSerializable.bits();
                } else {
                    class.serialize = Some(crate::ffi::zend_class_serialize_deny);
                    class.unserialize = Some(crate::ffi::zend_class_unserialize_deny);
                }
            }
        }

        for (iface, _) in self.interfaces {
            let interface = iface();
            assert!(
                interface.is_interface(),
                "Given class entry was not an interface."
            );

            unsafe { zend_do_implement_interface(class, ptr::from_ref(interface).cast_mut()) };
        }

        for (name, flags, _) in self.properties {
            unsafe {
                zend_declare_property(
                    class,
                    CString::new(name.as_str())?.as_ptr(),
                    name.len() as _,
                    &mut Zval::new(),
                    flags.bits().try_into()?,
                );
            }
        }

        for (name, value, _) in self.constants {
            let value = Box::into_raw(Box::new(value()?));
            unsafe {
                zend_declare_class_constant(
                    class,
                    CString::new(name.as_str())?.as_ptr(),
                    name.len(),
                    value,
                );
            };
        }

        if let Some(object_override) = self.object_override {
            class.__bindgen_anon_2.create_object = Some(object_override);
        }

        if let Some(register) = self.register {
            register(class);
        } else {
            panic!("Class {} was not registered.", self.name);
        }

        Ok(())
    }
Builds and registers the class.

# Errors

* [`Error::InvalidPointer`] - If the class could not be registered.
* [`Error::InvalidCString`] - If the class name is not a valid C string.
* [`Error::IntegerOverflow`] - If the property flags are not valid.
* If a method or property could not be built.

# Panics

If no registration function was provided.
src/builders/class.rs