summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--documentation/variables.html2
-rw-r--r--include/class.h44
-rw-r--r--include/classbase.h10
-rw-r--r--include/countable.h6
-rw-r--r--src/classbase.cpp41
5 files changed, 66 insertions, 37 deletions
diff --git a/documentation/variables.html b/documentation/variables.html
index 73f26bc..e2515d4 100644
--- a/documentation/variables.html
+++ b/documentation/variables.html
@@ -246,7 +246,7 @@ std::cout << value.call("format", "Y-m-d H:i:s") << std::endl;
</code></pre>
<h2>Functions</h2>
<p>
- When a Php::Value holds a <i>callable</i>, you can use the () operator
+ When a Php::Value object holds a <i>callable</i>, you can use the () operator
to call this function or method.
</p>
<p>
diff --git a/include/class.h b/include/class.h
index 3326507..ab4a3e0 100644
--- a/include/class.h
+++ b/include/class.h
@@ -18,8 +18,11 @@
/**
* Zend/SPL interfaces that we support
*/
-extern struct _zend_class_entry *spl_ce_Countable;
-extern struct _zend_class_entry *spl_ce_ArrayAccess;
+//extern struct _zend_class_entry *zend_ce_traversable;
+//extern struct _zend_class_entry *zend_ce_aggregate;
+//extern struct _zend_class_entry *zend_ce_iterator;
+extern struct _zend_class_entry *zend_ce_arrayaccess;
+//extern struct _zend_class_entry *zend_ce_serializable;
/**
* Set up namespace
@@ -43,36 +46,13 @@ public:
*/
Class(const char *name) : ClassBase(name)
{
- // check for special classes
- 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);
- }
+ // check for special classes, and register the interface if it does
+ // 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 only
+ // happens later when the all classes are registered (after the
+ // get_module() call)
+ if (std::is_base_of<ArrayAccess, T>::value) interface(&zend_ce_arrayaccess);
}
/**
diff --git a/include/classbase.h b/include/classbase.h
index 92e637d..05ab2f4 100644
--- a/include/classbase.h
+++ b/include/classbase.h
@@ -233,6 +233,16 @@ private:
static struct _zend_object_value createObject(struct _zend_class_entry *entry);
/**
+ * Function that is used to count the number of elements in the object
+ * If the user has implemented the Countable interface, this method will
+ * call the count() method
+ * @param val
+ * @param count
+ * @return int
+ */
+ static int countElements(zval *object, long *count TSRMLS_DC);
+
+ /**
* Retrieve pointer to our own object handlers
* @return zend_object_handlers
*/
diff --git a/include/countable.h b/include/countable.h
index 1b99463..d4c1823 100644
--- a/include/countable.h
+++ b/include/countable.h
@@ -7,7 +7,7 @@
* class MyClass : public Php::Base, public Php::Countable { ... }
*
* You will have to implement the count() method, which should return the
- * number of elements in the class
+ * number of elements in the object
*
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
* @copyright 2014 Copernica BV
@@ -26,9 +26,9 @@ class Countable
public:
/**
* Retrieve the number of items in the class
- * @return Value
+ * @return long
*/
- virtual Value count() = 0;
+ virtual long count() = 0;
};
diff --git a/src/classbase.cpp b/src/classbase.cpp
index 14c43d3..c9576f9 100644
--- a/src/classbase.cpp
+++ b/src/classbase.cpp
@@ -38,6 +38,16 @@ static ClassBase *cpp_class(zend_class_entry *entry)
}
/**
+ * Retrieve our C++ implementation object
+ * @param val
+ * @return ClassBase
+ */
+static ClassBase *cpp_class(const zval *val)
+{
+ return cpp_class(zend_get_class_entry(val));
+}
+
+/**
* Retrieve pointer to our own object handlers
* @return zend_object_handlers
*/
@@ -53,10 +63,11 @@ zend_object_handlers *ClassBase::objectHandlers()
if (initialized) return &handlers;
// initialize the handlers
- memcpy(&handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ memcpy(&handlers, &std_object_handlers, sizeof(zend_object_handlers));
// install custom clone function
handlers.clone_obj = &ClassBase::cloneObject;
+ handlers.count_elements = &ClassBase::countElements;
// remember that object is now initialized
initialized = true;
@@ -107,6 +118,34 @@ zend_object_value ClassBase::cloneObject(zval *val TSRMLS_DC)
}
/**
+ * Function that is used to count the number of elements in the object
+ *
+ * If the user has implemented the Countable interface, this method will
+ * call the count() method
+ *
+ * @param val
+ * @param count
+ * @return int
+ */
+int ClassBase::countElements(zval *object, long *count TSRMLS_DC)
+{
+ // we need the C++ class meta-information object
+ ClassBase *meta = cpp_class(object);
+
+ // does it implement the countable interface?
+ Countable *countable = dynamic_cast<Countable*>(meta);
+
+ // if it does not implement the Countable interface, we rely on the default implementation
+ if (!countable) return std_object_handlers.count_elements(object, count);
+
+ // call the count function
+ *count = countable->count();
+
+ // done
+ return SUCCESS;
+}
+
+/**
* Function that is called when an instance of the class needs to be created.
* This function will create the C++ class, and the PHP object
* @param entry Pointer to the class information