Hello everyone,
My name is David. I’m working on the refactoring of a PHP extension from “Zephir” language to a cleaner C language output.
I came across the fact that the extension uses a lot of “static” zend_string. No I want to convert those static zend_string into the intern string.
From what I read today based on PHP internal book website and PHP Source online, calling a Zen’s new interest string function create a string whose value is registered into a hash table. And then on a request in it this or that send interned string is then retrieved from the hash table instead of creating a new Zen string. Apart from the fact that every every news and intern strings have an immutable ref count.
My doubt is the following:
- Does ref counting increments/decrements when you create a Zend string using the static keyword?
- Assigning a new zend_string as interned zend_string, when the flag “IS_Interned_STRING” (if I remember correctly), the string is kinda garbage collected? (Do I need to free the string)?
Thanks for your support.
David.
Hi David,
On Wed, Sep 16, 2026 at 4:16 PM David Maye Kitenge <david.maye@seigisoft.com> wrote:
Hello everyone,
My name is David. I’m working on the refactoring of a PHP extension from “Zephir” language to a cleaner C language output.
I came across the fact that the extension uses a lot of “static” zend_string. No I want to convert those static zend_string into the intern string.
From what I read today based on PHP internal book website and PHP Source online, calling a Zen’s new interest string function create a string whose value is registered into a hash table. And then on a request in it this or that send interned string is then retrieved from the hash table instead of creating a new Zen string. Apart from the fact that every every news and intern strings have an immutable ref count.
My doubt is the following:
- Does ref counting increments/decrements when you create a Zend string using the static keyword?
static applies to the C variable, not the string’s reference-counting behaviour. A string held in static zend_string *s is still normally refcounted unless it is interned.
- Assigning a new zend_string as interned zend_string, when the flag “IS_Interned_STRING” (if I remember correctly), the string is kinda garbage collected? (Do I need to free the string)?
An actually interned string is managed by Zend/OPcache. The string copy/release helpers leave its refcount unchanged, and you should not free it directly.
To convert an existing string you own:
s = zend_new_interned_string(s);
Store the returned pointer, and the function will release the original string and return an existing interned one. Do not separately release the old pointer.
But, you should still use zend_string_release(s) when finished with your owned reference. It is a no-op for interned strings, but handles non-interned results, which these APIs can return with OPcache during a request.
For fixed extension strings needed across requests, initialize them during normal module startup (MINIT):
s = zend_string_init_interned("example", sizeof("example") - 1, true);
Strings interned during a request are not necessarily permanent; storing their pointer in a static variable does not extend their lifetime.
Regards,
Alex