summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/arrayaccess.h94
-rw-r--r--include/class.h36
-rw-r--r--include/classbase.h14
-rw-r--r--include/countable.h8
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 &params)
+ {
+ return offsetExists(params[0]);
+ }
+
+ /**
+ * Alternative set member function as it is initially called
+ * @param params
+ */
+ virtual void offsetSet(const Php::Parameters &params)
+ {
+ offsetSet(params[0], params[1]);
+ }
+
+ /**
+ * Alternative retrieve member function that is initially called
+ * @param params
+ * @return value
+ */
+ virtual Php::Value offsetGet(Php::Parameters &params)
+ {
+ return offsetGet(params[0]);
+ }
+
+ /**
+ * Alternative function to remove a member that is initally called
+ * @param params
+ */
+ virtual void offsetUnset(Php::Parameters &params)
+ {
+ 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;
+
};
/**