# Cache zend_function*

- Thread: https://externals.io/message/116542
- Original archive: https://news-web.php.net/php.internals/116542
- Started by Glash Gnome on 2021-11-28T21:22:44+00:00
- Messages: 2
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #116542 — Glash Gnome — 2021-11-28T21:22:44+00:00

URL: https://externals.io/message/116542#116542

Hello internals,

I'm doing the Cairo C API extension.
Also there is a wrapper written in php for the OOP side( example:
https://github.com/gtkphp/gtkphp/blob/main/lib/Cairo/Context.php)

So far, so good.

Now let's do the same thing with Gtk,
(https://github.com/gtkphp/gtkphp/blob/main/lib/Gtk/Widget.php#L7)
Luckily I can *store zend_function* pointer in the GtkWidgetClass*( C-like
OOP)

Finally, I do the same thing for GHashTable( C API + php OOP)
But now I need to *use a global zend_array/hash to store the overridden
methods*
for the same reasons as https://github.com/php/php-src/pull/7695


I think it is better( more generic, simple to understand) to *overload the
zend_class_entry* .

Do you think this is a good idea?
Is this possible ?
Do you have a solution for me?

Best regards,

---

## #116544 — tyson andre — 2021-12-01T00:22:53+00:00

URL: https://externals.io/message/116542#116544 · In reply to: #116542

Hi Glash Gnome,

> I'm doing the Cairo C API extension.
> Also there is a wrapper written in php for the OOP side( example:
> https://github.com/gtkphp/gtkphp/blob/main/lib/Cairo/Context.php)
> 
> So far, so good.
> 
> Now let's do the same thing with Gtk,
> (https://github.com/gtkphp/gtkphp/blob/main/lib/Gtk/Widget.php#L7)
> Luckily I can *store zend_function* pointer in the GtkWidgetClass*( C-like
> OOP)
> 
> Finally, I do the same thing for GHashTable( C API + php OOP)
> But now I need to *use a global zend_array/hash to store the overridden
> methods*
> for the same reasons as https://github.com/php/php-src/pull/7695
> 
> 
> I think it is better( more generic, simple to understand) to *overload the
> zend_class_entry* .
> 
> Do you think this is a good idea?
> Is this possible ?
> Do you have a solution for me?

Are you talking about all methods or just ArrayAccess?

If you're talking about https://github.com/gtkphp/php-ext-gtk-src/blob/master/php_glib/hash-table.c
it's possible to associate the table of overridden methods with the instance of the object,
and look it up in a C property of `intern->methods` to call the overridden method.

- If you're talking about avoiding doing a hash table lookup on every method call to an instance, you can use a `methods` property.

https://github.com/php/php-src/blob/PHP-8.1.0/ext/spl/spl_fixedarray.c#L241-L301 does that - see create_object, spl_fixedarray_new, and `spl_fixedarray_object *intern;`
(I implemented that in https://github.com/php/php-src/pull/6552)

It turns out review comments mentioned something similar about `ArrayAccess`.
At the time I wasn't as familiar with how it'd be done for all classes and work with inheritance, though I think it's possible.

- If `arraylike_funcs_ptr` were added to php for ArrayAccess, `instance->ce->arrayaccess_funcs_ptr->offsetget->scope != my_base_class_entry` could be used to check if the internal implementation was overridden

> Ideally these methods would be cached in the class_entry, but that's a larger change.


```c
// Declared in Zend/zend.h
// Initialized in Zend/zend_interfaces.c
// ....
	/* allocated only if class implements Iterator or IteratorAggregate interface */
	zend_class_iterator_funcs *iterator_funcs_ptr;
```

Regards,
Tyson
