pub fn new_interned(str: impl AsRef<[u8]>, persistent: bool) -> ZBox<Self> {
        let _lock = INTERNED_LOCK.lock();
        let s = str.as_ref();
        unsafe {
            let init = zend_string_init_interned.expect("`zend_string_init_interned` not ready");
            let ptr = init(s.as_ptr().cast(), s.len() as _, persistent)
                .as_mut()
                .expect("Failed to allocate memory for new Zend string");
            ZBox::from_raw(ptr)
        }
    }
Creates a new interned Zend string from a slice of bytes.

An interned string is only ever stored once and is immutable. PHP stores
the string in an internal hashtable which stores the interned
strings.

As Zend hashtables are not thread-safe, a mutex is used to prevent two
interned strings from being created at the same time.

Interned strings are not used very often. You should almost always use a
regular zend string, except in the case that you know you will use a
string that PHP will already have interned, such as "PHP".

# Parameters

* `str` - String content.
* `persistent` - Whether the string should persist through the request
boundary.

# Panics

Panics under the following circumstances:

* The function used to create interned strings has not been set.
* The function could not allocate enough memory for the Zend string.

# Safety

When passing `persistent` as `false`, the caller must ensure that the
object does not attempt to live after the request finishes. When a
request starts and finishes in PHP, the Zend heap is deallocated and a
new one is created, which would leave a dangling pointer in the
[`ZBox`].

# Example

```no_run
use ext_php_rs::types::ZendStr;

let s = ZendStr::new_interned("PHP", true);
```
src/types/string.rs