diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/arrayaccess.h | 94 | ||||
-rw-r--r-- | include/class.h | 36 | ||||
-rw-r--r-- | include/classbase.h | 14 | ||||
-rw-r--r-- | include/countable.h | 8 |
4 files changed, 142 insertions, 10 deletions
diff --git a/include/arrayaccess.h b/include/arrayaccess.h new file mode 100644 index 0000000..6ee3163 --- /dev/null +++ b/include/arrayaccess.h @@ -0,0 +1,94 @@ +/** + * ArrayAccess.h + * + * "Interface" that can be "implemented" by your class. If you do, you + * create your class like this: + * + * class MyClass : public Php::Base, public Php::ArrayAccess { ... } + * + * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> + * @copyright 2014 Copernica BV + */ + +/** + * Set up namespace + */ +namespace Php { + +/** + * Class definition + */ +class ArrayAccess +{ +public: + /** + * Check if a member is set + * @param key + * @return bool + */ + virtual bool offsetExists(const Php::Value &key) = 0; + + /** + * Set a member + * @param key + * @param value + */ + virtual void offsetSet(const Php::Value &key, const Php::Value &value) = 0; + + /** + * Retrieve a member + * @param key + * @return value + */ + virtual Php::Value offsetGet(const Php::Value &key) = 0; + + /** + * Remove a member + * @param key + */ + virtual void offsetUnset(const Php::Value &key) = 0; + + /** + * Alternative offsetExists as it is initially called + * @param params + * @return bool + */ + virtual Php::Value offsetExists(Php::Parameters ¶ms) + { + return offsetExists(params[0]); + } + + /** + * Alternative set member function as it is initially called + * @param params + */ + virtual void offsetSet(const Php::Parameters ¶ms) + { + offsetSet(params[0], params[1]); + } + + /** + * Alternative retrieve member function that is initially called + * @param params + * @return value + */ + virtual Php::Value offsetGet(Php::Parameters ¶ms) + { + return offsetGet(params[0]); + } + + /** + * Alternative function to remove a member that is initally called + * @param params + */ + virtual void offsetUnset(Php::Parameters ¶ms) + { + return offsetUnset(params[0]); + } +}; + +/** + * End namespace + */ +} + diff --git a/include/class.h b/include/class.h index a22b9a8..3326507 100644 --- a/include/class.h +++ b/include/class.h @@ -16,6 +16,12 @@ */ /** + * Zend/SPL interfaces that we support + */ +extern struct _zend_class_entry *spl_ce_Countable; +extern struct _zend_class_entry *spl_ce_ArrayAccess; + +/** * Set up namespace */ namespace Php { @@ -38,7 +44,35 @@ public: Class(const char *name) : ClassBase(name) { // check for special classes - if (std::is_base_of<Countable, T>::value) ClassBase::interface(Countable::implementation()); + if (std::is_base_of<Countable, T>::value) + { + // register the interface (we register a pointer-to-a-pointer here, + // because when this code runs (during the get_module() call), the + // interfaces are not yet initialized by the zend engine, this + // happens later when the all classes are registered (after the + // get_module() call) + interface(&spl_ce_Countable); + + // add the count method + method("count", &T::count, {}); + } + + // check for special classes + if (std::is_base_of<ArrayAccess, T>::value) + { + // register the interface (we register a pointer-to-a-pointer here, + // because when this code runs (during the get_module() call), the + // interfaces are not yet initialized by the zend engine, this + // happens later when the all classes are registered (after the + // get_module() call) + interface(&spl_ce_ArrayAccess); + + // add the count method + method("count", &T::offsetSet); + method("count", &T::offsetGet); + method("count", &T::offsetUnset); + method("count", &T::offsetExists); + } } /** diff --git a/include/classbase.h b/include/classbase.h index 3792fdb..92e637d 100644 --- a/include/classbase.h +++ b/include/classbase.h @@ -19,6 +19,7 @@ */ struct _zend_object_value; struct _zend_object_handlers; +struct _zend_class_entry; /** * Set up namespace @@ -66,6 +67,7 @@ public: _type(that._type), _methods(that._methods), _members(that._members), + _interfaces(that._interfaces), _entry(nullptr) {} /** @@ -77,6 +79,7 @@ public: _type(that._type), _methods(std::move(that._methods)), _members(std::move(that._members)), + _interfaces(std::move(that._interfaces)), _entry(that._entry) { // other entry are invalid now (not that it is used..., class objects are @@ -188,9 +191,16 @@ protected: * It does however make sense to support implementing extension-specific * interface. We may add this feature in the future. * + * This method is called _during_ the get_module() call when all classes + * are defined by the extension. However, at that time the Zend engine has + * not yet initialized the zend_class_entry's with the interface addresses. + * That's why we ask for a pointer-to-a-pointer. Later, when the classes + * are really registered, the Zend engine is with registering interfaces + * and the pointers point to a valid variable. + * * @param interface */ - void interface(struct _zend_class_entry *interface) + void interface(struct ::_zend_class_entry **interface) { // register the interface _interfaces.push_back(interface); @@ -274,7 +284,7 @@ private: * All interfaces that are implemented * @var std::list */ - std::list<struct _zend_class_entry*> _interfaces; + std::list<struct ::_zend_class_entry**> _interfaces; }; diff --git a/include/countable.h b/include/countable.h index 12d87d5..1b99463 100644 --- a/include/countable.h +++ b/include/countable.h @@ -25,17 +25,11 @@ class Countable { public: /** - * Implementation of the countable interface - * @return zend_class_entry* - * @internal - */ - static struct _zend_class_entry *implementation(); - - /** * Retrieve the number of items in the class * @return Value */ virtual Value count() = 0; + }; /** |